【发布时间】:2021-08-27 23:30:00
【问题描述】:
我正在尝试使用 一对一、一对多和 多对的 Laravel Eloquent 模型查询多个表许多关系。
我有一个forms 表、一个brands 表、一个users 表和一个brand_groups pivot 表。
每个表单都有一个品牌和一个用户:
forms
ID
user_id
brand_id
品牌没有任何外键:
brands
ID
用户没有任何外键:
users
ID
还有一个数据透视表可以创建多对多关系,用于创建拥有许多用户(如品牌成员)的品牌组:
brand_groups
brand_id
user_id
我正在尝试通过直接所有权 (forms.user_id) 或品牌会员资格获取属于用户的所有表单,该用户通过 brand_groups many 成为会员的所有品牌的所有表单到许多数据透视表。
例如,我们有 2 个品牌,2 个用户,1 个用户是 1 个品牌的成员:
brand(ID: 1)
brand(ID: 2)
user(ID: 1)
user(ID: 2)
brand_group(brand_id: 1, user_id: 1)
form(ID: 1, user_id: 1, brand_id: null)
form(ID: 2, user_id: null, brand_id: 1)
form(ID: 3, user_id: 2, brand_id: 1)
form(ID: 4, user_id: 1, brand_id: 2)
使用 Laravel Eloquent 模型(不是直接的 DB 外观调用),我想检索属于用户的所有表单。 user(ID:1) 有 3 种形式:
form(ID:1) 直接用户所有权form(ID:2) 用户是brand(ID:1) 组的成员,这是form(ID:2) 的品牌form(ID:3) 用户是brand(ID:1) 组的成员,这是form(ID:3)的品牌
我用Eloquent: Relationships - Has Many Through试了一下:
Has Many Through
“has-many-through”关系提供了一种通过中间关系访问远距离关系的便捷方式。
我试过这样:
class User extends Model
{
public function forms()
{
return Forms::hasManyThrough(
Form::class,
BrandGroups::class,
'brand_id',
'brand_id',
'id',
'form_id',
)->where('id', $this->id);
}
}
但我收到如下错误:
BadMethodCallException with message 'Call to undefined method App\Models\Form::brand_groups()'
编辑
经过一番挖掘,我设法想出了可以为用户返回所有表单的工作 MySQL 代码:
SELECT * FROM `forms`
WHERE EXISTS (
SELECT `brand_id`, `user_id`
FROM `brand_groups`
WHERE `forms`.`brand_id` = `brand_groups`.`brand_id`
AND `brand_groups`.`user_id` = 1
) OR `forms`.`user_id` = 1
现在我只需将该查询转换为一个雄辩的模型关系。
雄辩的模型
User.php
class User extends Authenticatable implements MustVerifyEmail
{
public function brands()
{
return $this
->belongsToMany(Brand::class, 'brand_groups')
->using(BrandGroups::class)
->as('member');
}
public function forms()
{
return $this->hasMany(Form::class, 'user_id');
}
}
Brand.php
class Brand extends Model
{
protected $table = 'brands';
public function forms()
{
return $this->hasMany(Form::class);
}
public function members()
{
return $this
->belongsToMany(User::class, 'brand_groups')
->using(BrandGroups::class)
->as('member');
}
}
Form.php
class Form extends Model
{
protected $table = 'forms';
public function owner()
{
return $this->belongsTo(User::class);
}
public function brand()
{
return $this->belongsTo(Brand::class);
}
}
更新
我设法找到一个查询来获取与这样的用户相关的所有表单:
class User extends Authenticatable implements MustVerifyEmail
{
...
public function allForms()
{
return Form::where(function ($q) {
$q->whereExists(function ($q) {
$q->from('brand_groups')
->where('forms.brand_id', DB::raw('brand_groups.brand_id'))
->where('brand_groups.user_id', $this->id);
})->orWhere('owner_id', $this->id);
});
}
}
如何将其转换为直接的User 模型雄辩关系?
【问题讨论】:
标签: mysql laravel eloquent eloquent-relationship