Laravel Eloquent - 获取过滤数据的嵌套关系
Laravel Eloquent - Get nested relationships with filtered data
假设我有以下模型:
类别-(hasMany/belongsTo)-子类别-(hasMany/belongsTo)-产品
这些模型在前端创建了一个可折叠的产品列表,如下所示:
Category1
- Subcategory1
- Product1
- Product2
Category2
- SubCategory3
- Product4
现在,我想搜索 Product1 并在保持关系 Category->Subcategory->Product 不变的情况下检索它,以便我可以像这样轻松地打印出来:
Category1
- Subcategory1
- Product1
我知道通过以下查询您可以搜索具有特定条件的产品的所有类别:
<?php
$Categories = Categories::whereHas('subcategories', function ($q) use ($request) {
$q->whereHas('products', function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
});
})
->get();
?>
但只有 returns 个类别。
然后我打算用以下资源将它们变成一个集合 class,然后我才知道我实际上只从上面的查询中获取类别:
$Collection = CategoriesResource::collection($Categories);
//------------------------------------------------
class CategoriesResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'subcategories' => $this->subcategories()->with('products')->get(),
];
}
}
我的问题是,我是否可以预先使用不同的查询,或者将条件传递给 with 语句,以便我只获得满足搜索条件的产品?理想情况下,我希望数据集中没有空类别或子类别,但如果无法以其他方式进行管理,那也没关系。
我也试过反向直接搜索products,得到有belongsTo关系的categories,但是不知道有什么可行的方法把Product->Categories逆向Categories->Products
编辑:
OMR 的解决方案对我有帮助,但我不得不添加另一个 whereHas 查询来过滤掉空的子类别。
$Categories = Categories::whereHas('subcategories', function ($q) use ($request) {
$q->whereHas('products', function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
});
})->with(['subcategories'=> function ($q) use ($request) {
$q->whereHas('products', function ($q) use($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
})->with(['products'=>function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
}]);
}])->get();
您可以在预先加载时重复相同的条件:
$Categories = Categories::whereHas('subcategories', function ($q) use ($request) {
$q->whereHas('products', function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
});
})->with(['subcategories'=> function ($q) use ($request) {
$q->with(['products'=>function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
}]);
}])->get();
假设我有以下模型:
类别-(hasMany/belongsTo)-子类别-(hasMany/belongsTo)-产品
这些模型在前端创建了一个可折叠的产品列表,如下所示:
Category1
- Subcategory1
- Product1
- Product2
Category2
- SubCategory3
- Product4
现在,我想搜索 Product1 并在保持关系 Category->Subcategory->Product 不变的情况下检索它,以便我可以像这样轻松地打印出来:
Category1
- Subcategory1
- Product1
我知道通过以下查询您可以搜索具有特定条件的产品的所有类别:
<?php
$Categories = Categories::whereHas('subcategories', function ($q) use ($request) {
$q->whereHas('products', function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
});
})
->get();
?>
但只有 returns 个类别。
然后我打算用以下资源将它们变成一个集合 class,然后我才知道我实际上只从上面的查询中获取类别:
$Collection = CategoriesResource::collection($Categories);
//------------------------------------------------
class CategoriesResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'subcategories' => $this->subcategories()->with('products')->get(),
];
}
}
我的问题是,我是否可以预先使用不同的查询,或者将条件传递给 with 语句,以便我只获得满足搜索条件的产品?理想情况下,我希望数据集中没有空类别或子类别,但如果无法以其他方式进行管理,那也没关系。
我也试过反向直接搜索products,得到有belongsTo关系的categories,但是不知道有什么可行的方法把Product->Categories逆向Categories->Products
编辑: OMR 的解决方案对我有帮助,但我不得不添加另一个 whereHas 查询来过滤掉空的子类别。
$Categories = Categories::whereHas('subcategories', function ($q) use ($request) {
$q->whereHas('products', function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
});
})->with(['subcategories'=> function ($q) use ($request) {
$q->whereHas('products', function ($q) use($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
})->with(['products'=>function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
}]);
}])->get();
您可以在预先加载时重复相同的条件:
$Categories = Categories::whereHas('subcategories', function ($q) use ($request) {
$q->whereHas('products', function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
});
})->with(['subcategories'=> function ($q) use ($request) {
$q->with(['products'=>function ($q) use ($request) {
$q->where('name', 'LIKE', "%$request->search%")
->orWhere('article_number', 'LIKE', "%$request->search%");
}]);
}])->get();