Laravel - 我应该在哪个模型上定义数据透视表?

Posted

技术标签:

【中文标题】Laravel - 我应该在哪个模型上定义数据透视表?【英文标题】:Laravel - on which model should I define the pivot table? 【发布时间】:2020-04-28 02:42:46 【问题描述】:

让我从Laravel doc这里展示场景:相关的数据库表是usersrolesrole_users。表名是不言自明的。

User模特:

class User extends Model

    /**
     * The roles that belong to the user.
     */
    public function roles()
    
        return $this->belongsToMany('App\Role');
    

文档接着说:

如前所述,确定表名 关系的连接表,Eloquent 会连接两个相关的模型 按字母顺序排列的名称。但是,您可以随意覆盖它 习俗。您可以通过将第二个参数传递给 belongsToMany 方法:

return $this->belongsToMany('App\Role', 'role_user');

然后它定义了关系的倒数:

Role模特:

class Role extends Model

    /**
     * The users that belong to the role.
     */
    public function users()
    
        return $this->belongsToMany('App\User');
    

然后它说:

由于我们重用了 belongsToMany 方法,所有的普通表 和关键自定义选项在定义逆时可用 多对多关系。

到目前为止我的理解:

pivot 表已在 User 模型中定义,文档说Role 模型中提供了所有常用的表和键自定义选项,具有多对多的反向关系。

所以似乎也可以选择在Role 模型中定义数据透视表。

Eloquent 默认会按字母顺序连接两个相关模型名称来定义数据透视表名称。

当数据透视表名称不符合默认约定时,我应该在哪个模型上定义数据透视表?

【问题讨论】:

在两个模型中定义 belongsToMany 关系时,您应该将数据透视表(非常规)名称作为第二个参数传递 【参考方案1】:
/**
* On the User model
*/
public function roles()

    return  $this->belongsToMany('App\Role', 'role_users', 'user_id', 'role_id')->withTimestamps();



/**
* On the roles model
*/
public function users()

    return  $this->belongsToMany('App\Role', 'role_users', 'role_id', 'user_id')->withTimestamps();

其中role_users是数据透视表,第一个参数是foreignPivotKey第二个参数是relatedPivotKey

通过这种方式,您可以在两个模型上建立完整的关系.. 您可以访问所有用户角色,反之亦然

【讨论】:

【参考方案2】:

在两者上定义它们。 UserRole 都使用 belongsToMany() 关系,表示多对多关系。

函数如下所示:

public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,
                                  $parentKey = null, $relatedKey = null, $relation = null)

所以

$this->belongsToMany(User::class, 'role_user');
// and
$this->belongsToMany(Role::class, 'role_user');

所以你可以在两个关系中定义$table 参数。在我看来,这也是更好的方法,因为这种对表名的神奇猜测会引起混乱。

【讨论】:

【参考方案3】:

尝试以这种方式在模型中切换 Eloquent 关系。但首先,请确保您使用模型,即

/** * 在用户模型上 */ 使用应用\角色; 公共功能角色() 返回 $this->belongsToMany(Role::class, 'role_users', 'user_id', 'role_id')->withTimestamps(); /** 其中 user_id 是引用 User 模型的表中的主键,而 role_id 是 Referenced/Foreign 表中的等效项。 **[我知道你明白我的意思。]** -- 同样适用于角色模型中的代码 **/
/** * 关于角色模型 */ 使用应用\用户; 公共功能用户() return $this->HasMany(User::class, 'role_users', 'role_id', 'user_id')->withTimestamps(); `

希望我没有误解你的问题。

【讨论】:

以上是关于Laravel - 我应该在哪个模型上定义数据透视表?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5 - 从数据透视表额外属性获取属性

Laravel 自定义数据透视表关系和急切加载?

Laravel 多列上的多对多同步()

laravel 使用 in 子句模型名称连接多态数据透视表

如何通过laravel创建数据透视表

Laravel 5.8 在数据透视表上保存一对多关系