如何在Laravel中有效地改变预加载数据的结构
我急切地在Laravel中加载一个产品的关系数据如何在Laravel中有效地改变预加载数据的结构,laravel,eloquent,Laravel,Eloquent,我急切地在Laravel中加载一个产品的关系数据 $product = Product::with('attributeValues.attribute')->find($id)->get(); 目前我得到的响应结构如下 [ { "product_id": 1, "product_name": "Shirt A", "attribute_values&quo
$product = Product::with('attributeValues.attribute')->find($id)->get();
目前我得到的响应结构如下
[
{
"product_id": 1,
"product_name": "Shirt A",
"attribute_values": [
{
"attribute_value_id": 1,
"attribute_value": "small",
"attribute": {
"attribute_id": 1,
"attribute": "size"
}
},
{
"attribute_value_id": 1,
"attribute_value": "medium",
"attribute": {
"attribute_id": 1,
"attribute": "size"
}
},
...
]
},
...
]
[
{
"product_id": 1,
"product_name": "Shirt A",
"attribute": [
{
"attribute_id": 1,
"attribute": "size",
"attribute_values": [
{
"attribute_value_id": 1,
"attribute_value": "small"
},
{
"attribute_value_id": 1,
"attribute_value": "medium"
}
]
},
...
]
},
...
]
我希望得到的结构如下
[
{
"product_id": 1,
"product_name": "Shirt A",
"attribute_values": [
{
"attribute_value_id": 1,
"attribute_value": "small",
"attribute": {
"attribute_id": 1,
"attribute": "size"
}
},
{
"attribute_value_id": 1,
"attribute_value": "medium",
"attribute": {
"attribute_id": 1,
"attribute": "size"
}
},
...
]
},
...
]
[
{
"product_id": 1,
"product_name": "Shirt A",
"attribute": [
{
"attribute_id": 1,
"attribute": "size",
"attribute_values": [
{
"attribute_value_id": 1,
"attribute_value": "small"
},
{
"attribute_value_id": 1,
"attribute_value": "medium"
}
]
},
...
]
},
...
]
模型的当前关系如下所示
class Product extends Model {
public function attributeValues(){
return $this->belongsToMany(AttributeValue::class, 'product_attributes');
}
}
class AttributeValue extends Model {
public function attribute(){
return $this->belongsTo(Attribute::class);
}
}
class Attribute extends Model { }
目前,通过使用产品和使用原始查询分别获取其属性,我成功地获得了正确的结构。我正试图以一种雄辩的方式完成这项任务
我的表格如下
class Product extends Model {
public function attributeValues(){
return $this->belongsToMany(AttributeValue::class, 'product_attributes');
}
}
class AttributeValue extends Model {
public function attribute(){
return $this->belongsTo(Attribute::class);
}
}
class Attribute extends Model { }
产品
产品属性
属性值
属性
最好的方法是使用JsonResource
只需定义ProductResource、attribyteValueResource和AttributeResource
以下是一个例子:
物业资源:
AttributeValue资源:
属性来源:
那就用它们吧:
$product = ProductResource::make(
Product::load('attributeValues.attribute')->find($id)
);
最好的方法是使用JsonResource
只需定义ProductResource、attribyteValueResource和AttributeResource
以下是一个例子:
物业资源:
AttributeValue资源:
属性来源:
那就用它们吧:
$product = ProductResource::make(
Product::load('attributeValues.attribute')->find($id)
);
那使用什么呢?我不是专家,但我会这样做:
$products->map(function($product){
$attribute = $product->attribute_values->groupBy('attribute.attribute')->map(function($groupAttribute,$key){
$attribute_values = $groupAttribute->map(function($attribute) {
return ['attribute_value_id'=>$attribute->attribute_value_id,'attribute_value'=>$attribute->attribute_value];
});
return ['attribute_id' => 1 ,'attribute'=> $key , 'attribute_values' => $attribute_values ];
});
return [
'product_id'=>$product->product_id,
'product_name'=>$product->product_name,
'attribute'=>$attribute
];
});
那使用什么呢?我不是专家,但我会这样做:
$products->map(function($product){
$attribute = $product->attribute_values->groupBy('attribute.attribute')->map(function($groupAttribute,$key){
$attribute_values = $groupAttribute->map(function($attribute) {
return ['attribute_value_id'=>$attribute->attribute_value_id,'attribute_value'=>$attribute->attribute_value];
});
return ['attribute_id' => 1 ,'attribute'=> $key , 'attribute_values' => $attribute_values ];
});
return [
'product_id'=>$product->product_id,
'product_name'=>$product->product_name,
'attribute'=>$attribute
];
});
只需执行以下操作,即可获得所需的结果
$product = Product::with('attribute.attributeValues')->find($id)->get();
只需执行以下操作,即可获得所需的结果
$product = Product::with('attribute.attributeValues')->find($id)->get();
您可以通过以下方式与inside一起使用:
您可以通过以下方式与inside一起使用:
这种方法的性能如何?我的意思是,有很多查询使用资源在后台运行,它的工作没有N+1问题,因为$this->whenLoaded方法正在使用,这种方法的性能如何?我的意思是,有很多查询是在后台使用资源运行的,它不会出现N+1问题,因为$this->whenLoaded方法正在使用
$product = Product::with('attribute.attributeValues')->find($id)->get();
$product = Product::with(['attributeValues'=>function($query){
$query->select(['attribute_value_id','attribute_value'])
->with('attribute:attribute_id,attribute');
}])->find($id)->get();