需要帮助来构建Eloquent的多对多关系(Laravel 5.1)

6
我将尝试构建一个类似于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');
    }
}

我做得对吗?你会如何创建这些模型?

1个回答

3

数据透视表规范

按照惯例,数据透视表的命名应该为tablename1_tablename2,其中tablename1字母顺序应优于tablename2。在这种情况下,group_members应该改为group_user。如果你更改了这个规则,你就不需要定义$table变量,所以如果你想要清理代码,可以将它们删除。

Eloquent关系

Eloquent关系是良好记录的,如果您有任何疑问,您可以参考代码文档,这非常简单明了:

hasOne

Define a one-to-one relationship.

hasMany

Define a one-to-many relationship.

hasManyThrough

Define a has-many-through relationship.

belongsTo

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

belongsToMany

Define a many-to-many relationship. 

当使用数据透视表时,您可以添加->withPivot(),Eloquent会自动查找您的传统命名的中间表。这些“中间”对象可能不会在演示层中使用,因此您甚至不需要为它们创建模型。
三向中间表
现在,就您的组成员身份而言,事情变得有点复杂。 hasManyThrough关系用于通过中间关系访问远程关系,并不是您要查找的内容。Laravel没有为这种类型的关系提供任何“即插即用”的功能,虽然有一个Laravel 4库可用于此目的,但它不太灵活,只提供了三向功能。现在这很好,但是如果您决定在将来扩展您的数据透视表呢?那么这将会破坏原有的关系。
重构数据库

我查看了你的表结构,发现它可以很容易地被重组:

UML Diagram

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

结果

用户

一个用户

  • 属于多个会员身份
  • 通过会员身份隶属于多个群组

代码:

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');
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接