【问题标题】:Need help to structure Eloquent Many to Many relationship (laravel 5.1)需要帮助构建 Eloquent 多对多关系(laravel 5.1)
【发布时间】:2015-12-10 08:06:45
【问题描述】:

我正在尝试构建一个“facebook 群组”风格的应用程序,其中包含充满成员的群组,每个成员都有一个成员类型(例如管理员、官员、用户..),每个群组都有自己的群组类型(公共、关闭,秘密)。

所以我创建了几个表:

users - (id, name ..)
groups - (id, name, group_type_id ..)  
group_types - (id, type)
group_members - (user_id, group_id, membership_type_id)
group_membership_types - (id, type)

我相信这是构建数据库的正确方法(如果我错了,请纠正我)。

现在我需要将其转换为 Eloquent 模型,因此我创建了模型,但在尝试建立它们之间的关系时感到非常困惑,我阅读了有关“pivot”和“hasManyThrough”的信息,并且更加困惑。

这些是我目前创建的模型:

class Group extends BaseModel
{ 
    protected $table = 'groups';

    public function Members() {
        return $this->belongsToMany('App\GroupMemeber');
    }

    public function Type() {
        return $this->belongsTo('App\GroupType');
    }
}

--

class GroupType extends BaseModel
{
   protected $table = 'group_types';

   protected $guarded = ['id', 'type'];

}

--

class GroupMemebershipType extends BaseModel
{
    protected $table = 'group_membership_types';
}

--

class GroupMember extends BaseModel
{

    protected $table = 'group_members';

    public function User() {
        return $this->belongsTo('App\User');
    }

    public function Group() {
        return $this->hasMany('App\Group');
    }

    public function MembershipType() {
        return $this->belongsTo('App\GroupMemebershipType');
    }
}

我做得对吗?您将如何创建这些模型?

【问题讨论】:

    标签: php mysql laravel-5 eloquent laravel-5.1


    【解决方案1】:

    数据透视表约定

    按照惯例,数据透视表命名为tablename1_tablename2,其中tablename1 按字母顺序取代tablename2。在这种情况下,group_members 应该是 group_user。如果更改此设置,则无需定义 $table 变量,因此您可以根据需要删除这些变量以清理代码。

    雄辩的关系

    Eloquent 关系是well documented,如果您不确定,可以随时参考代码文档,非常简单:

    有一个

    Define a one-to-one relationship.
    

    有很多

    Define a one-to-many relationship.
    

    hasManyThrough

    Define a has-many-through relationship.
    

    属于

    Define an inverse one-to-one or many relationship.
    

    belongsToMany

    Define a many-to-many relationship. 
    

    使用数据透视表时,您可以添加->withPivot(),Eloquent 会自动找到您惯用命名的数据透视表。您甚至不需要这些“中间”对象的模型,因为它们(可能)不会在您的表示层中使用。

    三向数据透视表

    现在,至于您的群组成员身份,事情变得有些复杂。 hasManyThrough 关系适用于 accessing distant relations via an intermediate relation,不是您要查找的。 Laravel 没有为这种类型的关系提供任何“即插即用”功能,虽然 is a Laravel 4 library 用于此目的,但它不是很动态,但只提供三向功能。现在这很好,但是如果您决定将来扩展您的数据透视表怎么办?那么这就会中断。

    重构数据库

    我查看了您的表格的结构,并注意到它可以很容易地重组:

    通过避免使用三向数据透视表,您的代码(和表结构)更易于维护且更具可读性。我认为这适用于任何具有三向关系的数据透视表,一个好的经验法则是通过使用更智能的表结构来避免它。

    结果

    用户

    一个用户

    • 属于许多成员
    • 通过会员资格拥有许多群组

    代码:

    class User extends Model
    {
        public function memberships() {
            return $this->belongsToMany('App\Membership');
        }
    
        public function groups() {
            return $this->hasManyThrough('App\Group', 'App\Membership');
        }
    }
    

    会员

    会员资格

    • 有很多用户
    • 属于一个组

    代码:

    class Membership extends Model
    {
        public function users() {
            return $this->hasMany('App\User');
        }
    
        public function group() {
            return $this->hasOne('App\Group');
        }
    }
    

    一组

    • 拥有许多会员资格
    • 通过会员资格拥有许多用户

    代码:

    class Group extends Model
    {
        public function memberships() {
            return $this->hasMany('App\Membership');
        }
    
        public function users() {
            return $this->hasManyThrough('App\User', 'App\Membership');
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 2016-04-12
      • 2016-02-11
      • 2015-03-11
      • 1970-01-01
      相关资源
      最近更新 更多