php - 需要帮助构建 Eloquent 多对多关系(laravel 5.1)

标签 php mysql laravel-5 eloquent laravel-5.1

我正在尝试构建一个“facebook 群组”风格的应用程序,其中包含充满成员的群组,每个成员都有一个成员类型(例如管理员、官员、用户……),每个群组都有其群组类型(公共(public)、关闭, 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)

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

现在我需要将它转换为 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');
    }
}

我做的对吗?你将如何创建这些模型?

最佳答案

数据透视表约定

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

Eloquent 关系

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

有一个

Define a one-to-one relationship.

有很多

Define a one-to-many relationship.

有许多通过

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为此,它不是很动态,但只提供三向功能。现在这很好,但是如果您决定在将来扩展您的数据透视表怎么办?然后这将中断。

重构数据库

我查看了您的表格结构,发现它可以很容易地进行重组: UML Diagram

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

结果

用户

一个用户

  • 属于许多成员(member)
  • 通过成员(member)资格拥有许多群组

代码:

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

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

成员(member)资格

成员(member)资格

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

代码:

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

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

一组

  • 有很多成员(member)
  • 通过成员(member)制拥有很多用户

代码:

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

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

关于php - 需要帮助构建 Eloquent 多对多关系(laravel 5.1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32562823/

相关文章:

php - 用于 php 文件的 javaScript,不要等待回复

PHP: self::vs parent::with 扩展

php - SQL查询如何从多行返回数据

php - Laravel 事件 : updating vs updated?

php - Laravel 5.2 - Eloquent 模型查询

php - 为什么在使用 file_get_contents() 时出现 500 错误,但在浏览器中有效?

php - 在 PHP 中使用 ImageMagick 从命令行调整图像大小

mysql总和显示十进制类型的错误答案

mysql - SQL-phpmyadmin(有重复记录的问题)

php - Laravel 5 文件删除错误