首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从-many到relation connected to -one to relation relation (laravel7)检索集合的最佳方法

从-many到relation connected to -one to relation relation (laravel7)检索集合的最佳方法
EN

Stack Overflow用户
提问于 2020-08-22 17:34:08
回答 2查看 37关注 0票数 1

您可以在下图中看到我的数据库的一部分:

此设计的目标是使管理员能够将alerts发送到由centerfield(动态)过滤的users。如果你认为这是一个糟糕的设计,请告诉我(请说明为什么以及如何改进我的设计)。

现在,如果我想要获得用户的警报,我应该这样做:

代码语言:javascript
复制
    $userAlerts = collect();

    auth()->user()->branch()->first()->groups()->get()->each(function ($item, $key) use ($userAlerts) {
        $item->alerts()->get()->each(function ($item, $key) use ($userAlerts) {
            $userAlerts->push($item);
        });
    });

这段代码很可笑,我不想这样做。

相反,我想做这样的事情:

代码语言:javascript
复制
    $alerts = auth()->user()->branch()->groups()->alerts() // i want this // method 1

代码语言:javascript
复制
    $alerts = auth()->user()->alerts() //or maybe this // method 2

我可以在不改变数据库的情况下做这样的事情吗?(方法1或2)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-22 18:15:02

您可以在分支模型上使用laravel的默认Has Many Through来挑选相关的警报

代码语言:javascript
复制
class Branch extends Model
{

    public function alerts()
    {
        return $this->hasManyThrough(
            'App\Models\Alert',
            'App\Models\Group',
            'branch_id', // Foreign key on alert table...
            'group_id', // Foreign key on group table...
            'id', // Local key on branch table...
            'id' // Local key on group table...
        );
    }

}

使用这种方式,您可以查询用户警报,如下所示

代码语言:javascript
复制
$alerts = auth()->user()->branch()->alerts()

或者,您可以使用第三方软件包eloquent-has-many-deep,它可以轻松地在多个相关模型上扩展hasManyThrough

代码语言:javascript
复制
class User extends Model
{
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function alerts()
    {
        return $this->hasManyDeep(
            'App\Models\Alert',
            ['App\Models\Branch', 'App\Models\Group'], // Intermediate models, beginning at the far parent (User).
            [
               'user_id', // Foreign key on the "branch" table.
               'branch_id',    // Foreign key on the "group" table.
               'group_id'     // Foreign key on the "alert" table.
            ],
            [
              'id', // Local key on the "user" table.
              'id', // Local key on the "branch" table.
              'id'  // Local key on the "group" table.
            ]
        );
    }
}

并且您可以直接获得用户警报,如下所示

代码语言:javascript
复制
$alerts = auth()->user()->alerts()

最后,您可以在用户模型中定义警报关系,通过添加一些joins来直接拉取相关的警报

代码语言:javascript
复制
class User extends Model
{
  
    public function alerts()
    {
        return $this->belongsTO('App\Branch', 'branch_id')
            ->join('branch_group', 'branches.id', '=', 'branch_group.branch_id')
            ->join('alerts', 'branch_group.group_id', '=', 'alerts.group_id')
            ->select('alerts.*');
    }

}
票数 2
EN

Stack Overflow用户

发布于 2020-09-28 16:23:30

到目前为止,使用这个repo是我找到的最好的解决方案。

https://github.com/johnnyfreeman/laravel-custom-relation

在这种情况下:基于文档

代码语言:javascript
复制
class User extends Model {
   use HasCustomRelations;

    public function alerts()
    {
        return  $this->custom(
            Alert::class,
            // add constraints
            function ($relation) {
                $relation->getQuery()
                    ->join('branch_group as bg', 'bg.group_id', '=', 'alerts.group_id')
                    ->join('users as u', 'u.branch_id', '=', 'bg.branch_id')
                    ->where('u.id', $this->id);
            },
            // add eager constraints
            function ($relation, $models) {
                $relation->getQuery()->whereIn('users.id', $relation->getKeys($models));
            }
        );
    }

}

通过这种方式,我可以受益于所有的早期关系方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63534681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档