需要帮助来构建Eloquent Many to Many关系(laravel 5.1)

Or *_*har 6 php mysql eloquent laravel-5 laravel-5.1

我正在尝试构建一个'facebook groups'样式应用程序,其中包含充满成员的组,每个成员都有一个成员类型(例如admin,officer,user ..),每个组都有其组类型(public,closed,secret ).

所以我创建了几个表:

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)
Run Code Online (Sandbox Code Playgroud)

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

现在我需要将它转换为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');
    }
}
Run Code Online (Sandbox Code Playgroud)

-

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

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

}
Run Code Online (Sandbox Code Playgroud)

-

class GroupMemebershipType extends BaseModel
{
    protected $table = 'group_membership_types';
}
Run Code Online (Sandbox Code Playgroud)

-

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');
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Osk*_*D90 3

数据透视表约定

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

雄辩的关系

Eloquent 关系有详细记录,如果您不确定,可以随时参考代码文档,这非常简单:

有一个

Define a one-to-one relationship.
Run Code Online (Sandbox Code Playgroud)

有很多

Define a one-to-many relationship.
Run Code Online (Sandbox Code Playgroud)

有很多通过

Define a has-many-through relationship.
Run Code Online (Sandbox Code Playgroud)

属于

Define an inverse one-to-one or many relationship.
Run Code Online (Sandbox Code Playgroud)

属于多个

Define a many-to-many relationship. 
Run Code Online (Sandbox Code Playgroud)

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

三向数据透视表

现在,对于您的组成员身份,事情变得有点复杂。该hasManyThrough关系用于通过中间关系访问远程关系,而不是您正在寻找的。Laravel 不为这种类型的关系提供任何“即插即用”功能,虽然有一个用于此目的的 Laravel 4 库,但它不是很动态,仅提供三向功能。现在这很好,但是如果您决定将来扩展数据透视表怎么办?那么这个就会被打破。

重构数据库

我查看了你的表的结构,发现它可以很容易地重组: 统一建模语言图

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

结果

用户

一个用户

  • 属于许多会员资格
  • 通过会员资格拥有许多团体

代码:

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

    public function groups() {
        return $this->hasManyThrough('App\Group', 'App\Membership');
    }
}
Run Code Online (Sandbox Code Playgroud)

会员资格

会员资格

  • 有很多用户
  • 属于一个团体

代码:

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

    public function group() {
        return $this->hasOne('App\Group');
    }
}
Run Code Online (Sandbox Code Playgroud)

团体

一个小组

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

代码:

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

    public function users() {
        return $this->hasManyThrough('App\User', 'App\Membership');
    }
}
Run Code Online (Sandbox Code Playgroud)