Laravel 关系我应该使用 hasManyThrough 还是 belongsToMany?嵌套 3 个表
Posted
技术标签:
【中文标题】Laravel 关系我应该使用 hasManyThrough 还是 belongsToMany?嵌套 3 个表【英文标题】:Laravel Relations Should I use hasManyThrough or belongsToMany? Nesting 3 Tables 【发布时间】:2021-12-29 04:04:09 【问题描述】:我之前问过这个问题,但它的格式不同且不正确。 交易是,我有 4 张桌子要嵌套。 我想要包含 measurement_data 的 Measurement_data ,其中包含 measurement_fields ,其中包含 measure_type (仅显示重要字段)。 到目前为止,我在 Measurement Data 中拥有除 MeasurementFields 之外的所有内容。
我的桌子:
measurements
- id
- client_id (not really important now)
measurement_data
- id
- measurement_id
- measurement_field_id
measurement_fields
- id
- type_id
measurement_types
- id
- name
我已经尝试过 hasManyThrough 和 belongsToMany,但我无法让它们中的任何一个工作。这就是我现在的模型中的内容:
测量模型
protected $fillable = [
'client_id',
];
public $timestamps = false;
public function clients()
return $this->belongsTo(Client::class, 'client_id');
public function measurement_datas()
return $this->hasMany(MeasurementData::class);
public function measurement_fields()
return $this->belongsToMany(MeasurementField::class, 'measurement_fields', 'measurement_id', 'measurement_field_id')
->withPivot([
'type_id',
'name',
'enabled',
]);
测量数据模型
protected $fillable = [
'measurement_id',
'measurement_field_id',
'data',
];
public function measurement()
return $this->belongsTo(Measurements::class, 'measurement_id');
MeasurementField 模型
protected $table = 'measurement_fields';
protected $fillable = [
'type_id',
'name',
'enabled',
];
public $timestamps = false;
public function measurement_type()
return $this->belongsTo(MeasurementType::class, 'type_id');
MeasurementType 模型
protected $table = 'measurement_types';
protected $fillable = [
'name',
];
public function measurement_field()
return $this->hasMany(MeasurementField::class);
我的控制器MeasurementController
public function index()
return JsonResource::collection(Measurement::with(['clients', 'measurement_datas', 'measurement_fields'])->get());
我会很感激任何帮助,因为我已经坚持了一段时间了。谢谢你:)
【问题讨论】:
如何在控制器中调用它们? 我将编辑我的问题以包含控制器,忘记了。一瞬间.. 【参考方案1】:好的,首先,您的 MeasurementData@measurement
方法使用 Measurements
,而它应该是 Measurement
(单数 - 匹配类名)。
其次,您在belongsToMany
中引用的表应该是数据透视表,而不是您想要的关系表。 withPivot
将不起作用/不需要,因为这些字段不是数据透视表的一部分。此外,如果不遵循 Laravel 的 naming convention,您只需定义关系的列名。这就是您的 measurement_fields
方法的样子:
public function measurement_fields()
return $this->belongsToMany(MeasurementField::class, 'measurement_data');
或者,您可以在MeasurementData
和MeasurementField
之间建立关系(如果您还没有这样做的话),然后使用nested eager loading。将以下内容添加到您的 MeasurementData
模型中:
public function measurement_field()
return $this->belongsTo(MeasurementField::class);
然后您可以使用以下方式加载信息:
Measurement::with(['clients', 'measurement_datas.measurement_field.measurement_type', 'measurement_fields'])
【讨论】:
感谢您的帮助,但是,现在我在我的 measurement_fields 对象中获得了数据透视数据(measurement_id 和 measure_field_id)。但我想要的是在 measure_data 对象中获取信息,这样我就可以访问名称和其他字段等。最终我想要一个禁用字段和数据的函数,这样它就不会出现在我的 CRUD 上 @bgeertsema2000 您可以删除控制器中的数据透视数据或为此创建自定义资源。或者,您可以通过数据关系加载字段关系。 出于某种原因,我只从 measure_fields 中获取外键,而不是其他的:"data":["id":1,"client_id":1,"clients":" id":1,"clientnumber":"284824367384Ger","measurement_fields":["id":1,"type_id":1,"name":"test1","enabled":1,"pivot": "measurement_id":1,"measurement_field_id":1,"id":2,"type_id":2,"name":"test2","enabled":0,"pivot":"measurement_id" :1,"measurement_field_id":2,"id":3,"type_id":1,"name":"test3","enabled":1,"pivot":"measurement_id":1," measure_field_id":3] 我可以看到您在measurement_fields
中也收到了name
和enabled
。 pivot
是在检索 BelongsToMany
关系时添加的额外字段。
是的,我明白了,但是我没有得到每个数据条目附加的字段的数据,我希望它在measurement_data中显示measurement_field以上是关于Laravel 关系我应该使用 hasManyThrough 还是 belongsToMany?嵌套 3 个表的主要内容,如果未能解决你的问题,请参考以下文章
使用数据透视表关系提高大型数据集的性能(使用 Laravel)