【问题标题】:Laravel/Eloquent - Modeling a HasOne relationship via a BelongsToMany relationshipLaravel/Eloquent - 通过 BelongsToMany 关系建模 HasOne 关系
【发布时间】:2020-03-04 09:14:41
【问题描述】:

假设我有四张桌子:

  • 用户
  • 群组
  • 活动
  • group_activities

其中一个组可以有任意数量的activities,一个活动可以通过它们的中间表group_activities属于任意数量的groups,并且一个用户通过users.group_id属于一个组。我想正确建模usersactivities 之间的关系,以便用户可以拥有任何一个活动,但前提是该用户所属的组与该活动有关系。 p>

HasOneThrough 似乎在这里不起作用,因为与用户相关的组有多个活动。 HasManyThrough 不起作用,因为用户只能拥有一个。

我想正确地建模这种关系,以便可以通过 Nova 关系字段自动选择它,但我正在努力弄清楚我将如何做到这一点。我的第一个想法是与一组子查询的 HasOneThrough 关系,但我无法拼凑出从哪里开始。

我将如何做到这一点,或者相反,是否可以通过 Eloquent 的自动关系系统来实现?

【问题讨论】:

    标签: php laravel eloquent laravel-nova


    【解决方案1】:

    为确保我们对您的关系有相同的看法:

    组和活动之间的关系是多对多关系 (Many To Many - Larvel Documentation)。

    group_activities 表是数据透视表。

    用户和组之间的关系是一对多关系One To Many - Larvel Documentation 和它的逆One To Many (Inverse) - Larvel Documentation

    要真正回答您的问题:

    如果您想使用从用户到他们的活动的快捷方式,“Has Many Through”是正确的方法。如果一个组可以有任意多个活动,并且一个用户属于一个组,则该用户将通过该组与这些任意多个活动相关联-因此具有很多通过。请注意,这并不是真正的独立关系,它只是一个方便的快捷方式。

    如果您不想直接将用户与单个 Activity 关联,则需要通过用户和 Activity 之间单独的一对多关系来实现。

    我不完全确定我是否正确解释了您的问题,因此以下只是一个假设,但您是否要确保用户只能与也与用户组相关联的活动相关联?所以要按组限制可能的活动?如果是这种情况,您只需检查所选活动是否在与用户组关联的活动中:

    你的关系是这样建立的:

    class User {
    
        public function activity(){
            return $this->belongsTo('App\Activity');
        }
    
        public function possibleActivities(){
             return $this->hasManyThrough('App\Activity','App\Group');
        }
    }
    

    您可以像这样检查和关联活动:

    if( $user->possibleActivities()->contains( $activity ) ){
        $user->activity()->associate($activity);
    }
    

    【讨论】:

    • 这应该在大多数情况下工作。它不会与 Nova 的场魔法一起飞行,但我可以制作伪场并在观察者中处理逻辑就足够了。
    • 对于任何想将它用于 Laravel Nova 的人,就像我一样 - 我采用的方法是使用 onlyOnForms() 方法从 $user->possibleActivities()->pluck('label', 'activities.id') 生成一个 Select 下拉列表 - 然后生成一个自定义字段hideWhenUpdating()hideWhenCreating() 将活动及其标签与用户上的 getAttribute 方法链接起来,该方法使用 $user->activity 访问器。
    猜你喜欢
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2016-12-20
    • 2015-08-21
    • 2020-10-06
    • 1970-01-01
    相关资源
    最近更新 更多