Laravel 5 中何时使用 belongsToMany 与 hasMany
When to use belongsToMany vs hasMany in Laravel 5
有很多类似的问题,但我发现接受的答案并不令人满意。据我所知,现有问题中没有明确的答案。
对于 belongsTo() 与 hasOne(),常见的答案似乎是 'user' 和 'phone' 关系。一个用户有一个phone号,一个phone号属于用户。这在 Laravel 文档中也有详细解释:
https://laravel.com/docs/5.2/eloquent-relationships
解释是 'Phone' 模型持有外键 'user_id'。因此,没有 'User' 模型就无法存在 phone 号码,但是没有 phone 就可以存在用户。如果删除用户模型,则应删除相关的 Phone 模型。到目前为止一切都很好...
然而,当您有许多使用枢轴 table 的关系时,它会变得复杂。 (外键参数不再适用,因为它存在于枢轴 table 中)。
假设我们有模型公司和用户。公司可以有很多用户,用户可以有很多公司。然后我们有一个名为 company_user 的枢轴 table,它包含 company_id 和 user_id 行。
假设一个用户可以属于许多不同的公司,公司可以属于这些集合相交的许多用户。
假设我们有:
Companies:
Company1
Company2
Company3
Users:
User1
User2
User3
Pivot:
User1, Company1
User1, Company2
User2, Company1
User2, Company2
这里User1和User2都是Company1的成员,反之亦然。但是 Company3 和 User3 没有任何关系...(但是 Company 可以在没有 User 的情况下存在,反之亦然)。
所以从本质上讲,说 User belongsToMany Companies 和 Company belongsToMany Users 是正确的,同时我们也可以说 User hasMany Companies 和 Company hasMany Users。
现在,如果我们想到一个类比,人们可能会想出一个解释,公司有用户,但用户在那里工作,所以他们属于公司。但是,如果有问题的用户是公司的所有者,那么用户拥有公司,而公司属于用户。
因为用户和公司都可以单独生活。我们可以说我们必须使用 hasMany 关系吗? (因为之前的 hasOne 意味着 User 可以在没有 Phone 的情况下存在,但是 Phone 不能在没有 User 的情况下存在,因为 belongsTo 需要 User 才能存在?)
在此示例中映射公司-用户关系的正确方法是什么?为什么?或者使用哪一个有什么不同?
谢谢!
您陷入了语义杂草。将 Laravel 从等式中取出一秒钟,您的原始数据库结构是正确的。您通过中间联接 table 建立了多对多关系。连接 table 的存在意味着用户和公司之间可以存在某种形式的关系,但它并不暗示这意味着什么或它需要存在。对于您的用户受雇与拥有公司的示例,您应该在连接 table 上添加一个属性,例如 'role' 可以是 'owner'、'employee'、'board-member',等。那么当你访问具体公司和用户的关系时,你就知道关系是什么意思了。
将 Laravel 添加回等式,我相信通过 Eloquent 合并的建议方法是使用 belongsToMany 方法。但请记住,这只是 ORM 用来定义这种多对多关系的快捷方式。当您使用实际的查询构建器功能时:
$user->companies
$company->users
很明显,您希望在连接的另一端关联模型。
编辑:
要回答标题问题,请对多对多关系使用 belongsToMany。如果您与 belongsTo 有单向关系,请使用 hasMany。
有很多类似的问题,但我发现接受的答案并不令人满意。据我所知,现有问题中没有明确的答案。
对于 belongsTo() 与 hasOne(),常见的答案似乎是 'user' 和 'phone' 关系。一个用户有一个phone号,一个phone号属于用户。这在 Laravel 文档中也有详细解释: https://laravel.com/docs/5.2/eloquent-relationships
解释是 'Phone' 模型持有外键 'user_id'。因此,没有 'User' 模型就无法存在 phone 号码,但是没有 phone 就可以存在用户。如果删除用户模型,则应删除相关的 Phone 模型。到目前为止一切都很好...
然而,当您有许多使用枢轴 table 的关系时,它会变得复杂。 (外键参数不再适用,因为它存在于枢轴 table 中)。
假设我们有模型公司和用户。公司可以有很多用户,用户可以有很多公司。然后我们有一个名为 company_user 的枢轴 table,它包含 company_id 和 user_id 行。
假设一个用户可以属于许多不同的公司,公司可以属于这些集合相交的许多用户。
假设我们有:
Companies:
Company1
Company2
Company3
Users:
User1
User2
User3
Pivot:
User1, Company1
User1, Company2
User2, Company1
User2, Company2
这里User1和User2都是Company1的成员,反之亦然。但是 Company3 和 User3 没有任何关系...(但是 Company 可以在没有 User 的情况下存在,反之亦然)。
所以从本质上讲,说 User belongsToMany Companies 和 Company belongsToMany Users 是正确的,同时我们也可以说 User hasMany Companies 和 Company hasMany Users。
现在,如果我们想到一个类比,人们可能会想出一个解释,公司有用户,但用户在那里工作,所以他们属于公司。但是,如果有问题的用户是公司的所有者,那么用户拥有公司,而公司属于用户。
因为用户和公司都可以单独生活。我们可以说我们必须使用 hasMany 关系吗? (因为之前的 hasOne 意味着 User 可以在没有 Phone 的情况下存在,但是 Phone 不能在没有 User 的情况下存在,因为 belongsTo 需要 User 才能存在?)
在此示例中映射公司-用户关系的正确方法是什么?为什么?或者使用哪一个有什么不同?
谢谢!
您陷入了语义杂草。将 Laravel 从等式中取出一秒钟,您的原始数据库结构是正确的。您通过中间联接 table 建立了多对多关系。连接 table 的存在意味着用户和公司之间可以存在某种形式的关系,但它并不暗示这意味着什么或它需要存在。对于您的用户受雇与拥有公司的示例,您应该在连接 table 上添加一个属性,例如 'role' 可以是 'owner'、'employee'、'board-member',等。那么当你访问具体公司和用户的关系时,你就知道关系是什么意思了。
将 Laravel 添加回等式,我相信通过 Eloquent 合并的建议方法是使用 belongsToMany 方法。但请记住,这只是 ORM 用来定义这种多对多关系的快捷方式。当您使用实际的查询构建器功能时:
$user->companies
$company->users
很明显,您希望在连接的另一端关联模型。
编辑:
要回答标题问题,请对多对多关系使用 belongsToMany。如果您与 belongsTo 有单向关系,请使用 hasMany。