Laravel Eloquent如何查询分类下所有属性及对应条目属性内容
解决方案
首先需要先修正一处模型关联错误,否则后续查询无法正常运行:原Group模型中categories关联写法有误,Group和Category为多对多关联,中间表为group_categories,需要将原有hasManyThrough改为belongsToMany:
class Group extends Model { // 修正多对多关联 public function categories() { return $this->belongsToMany(Category::class, 'group_categories'); } public function items() { return $this->hasMany(Item::class); } }
场景1:查询指定分类下的所有属性,以及对应条目的属性内容
直接从Category模型出发,使用嵌套预加载关联即可,假设指定分类ID为$categoryId:
// 预加载分类下的属性、属性对应的内容、内容归属的条目 $category = Category::query() ->where('id', $categoryId) ->with([ 'properties', // 该分类下所有可用属性 'properties.contents.item' // 属性对应的所有条目内容 ]) ->first(); // 取值示例 foreach ($category->properties as $property) { echo "属性名:{$property->name},属性类型:{$property->type}".PHP_EOL; // 遍历该属性下所有条目对应的内容 foreach ($property->contents as $content) { echo "条目名称:{$content->item->name},属性内容:{$content->content}".PHP_EOL; } }
场景2:查询单个条目在指定分类下的所有可用属性及对应内容
如果你的需求是针对某个已知的Item,获取它在指定分类下的所有属性和已填写的内容,可以按以下方式实现:
// 假设已知条目ID为$itemId,目标分类ID为$targetCategoryId $item = Item::query() ->where('id', $itemId) ->with([ // 预加载分组关联的指定分类 'group.categories' => function ($query) use ($targetCategoryId) { $query->where('categories.id', $targetCategoryId); }, 'group.categories.properties', // 分类下的所有可用属性 'contents.property' // 该条目已保存的所有属性内容 ]) ->first(); // 将已有的属性内容按属性ID做索引,方便后续快速匹配 $contentMap = $item->contents->keyBy('category_prop_id'); // 组装属性+内容结果 $itemProps = $item->group->categories->first()->properties->map(function ($prop) use ($contentMap) { return [ 'prop_id' => $prop->id, 'prop_name' => $prop->name, 'prop_type' => $prop->type, 'content' => $contentMap->has($prop->id) ? $contentMap->get($prop->id)->content : null ]; }); // 最终$itemProps就是当前条目在指定分类下的所有可用属性,以及对应内容(未填写则为null)
性能优化建议
如果数据量较大,可以在预加载时添加select条件限定查询字段,不需要的关联层级不要加载,避免不必要的性能损耗。
内容的提问来源于stack exchange,提问作者Sestriel
相关产品推荐
相关产品推荐

