mattsplat/dynamic-loading

动态加载未定义的关系

dev-master 2023-08-02 15:21 UTC

This package is auto-updated.

Last update: 2024-08-31 00:49:11 UTC


README

安装

composer require mattsplat/dynamic-loading

基本用法

您不需要连接表的外键。

$collectionOfModels->dynamicLoad(
        'name_of_custom_relation', // this is only defined here and where the data is accessed
        function ($model) {
            
            return RelatedModel::where('conditions', $model->conditions)->orderBy('condition');
     
        },

        'relation_key', // Optional if this does not exist it will be created as an alias

        'model_key' // Optional used to match the records back to the model
    );

如果relation_key和model_key未定义,它们将被创建 model_key: {primary_key} relation_key: {model_name}_{primary_key}

示例

排名用户不以'r'结尾

给定以下数据库结构,很容易添加当前排名的关系,但不添加与用户不相关排名的关系。

users

  • id
  • rank_id

ranks

  • id
  • name
    /// add r ranks relation that gets all ranks that start with r except the user's current rank 
    $users = $users->dynamicLoad(

        'r_ranks', 

        fn($m) => Rank::where('name', 'like', '%r')->where('id', '!=', $m->rank_id)
    );

这将产生1个查询,并将匹配的ranks查询作为关系添加到用户集合中。

结果

$users[0] => [
        'id' => 1,
        'rank_id' => 5,
        'r_ranks' => [
                0 => [
                    'id' => 6,
                    'name' => 'Performer'
                
                ],
                1 =>  => [
                    'id' => 8,
                    'name' => 'Racer'
                
                ]
        ]
]

这是通过在每个模型中注入user_id并在子查询中使用union组合子查询来实现的。

生成的查询

select * from (select *, 1 as user_id from "ranks" where "name" like '%r' and "id" != 1) 
        union select * from (select *, 2 as user_id from "ranks" where "name" like '%r' and "id" != 1) 
        union select * from (select *, 3 as user_id from "ranks" where "name" like '%r' and "id" != 1) 
        union select * from (select *, 4 as user_id from "ranks" where "name" like '%r' and "id" != 1)

在这里,我们在logins表上有匹配的用户_id,但如果我们只想获取最新的登录,我们必须返回它们所有,使用典型的关系。相反,我们可以使用1个查询动态加载用户集合中的最新登录。

users

  • id

logins

  • id
  • created_at
  • user_id
   // get the latest login for user
    $users = $users->dynamicLoad(

        'latest_login', 

        fn($m) => Login::where('user_id', '!=', $m->id)->latest()->limit(1)

    );

结果看起来可能像这样

$users => [
        'id' => 1,
        'latest_login' => [
                0 => [
                    'id' => 6,
                    'created_at' => '2020-01-20 10:10:00'
                
                ],
        ]
],
[
        'id' => 2,
        'latest_login' => [
                0 => [
                    'id' => 78,
                    'created_at' => '2020-01-25 15:10:00'
                
                ],
        ]
],