给出以下两个表和关系:
模型容器:id,名称,desc,created_at,updated_at
public function items()
{
return $this->hasMany('App\Models\Items', 'container_id', 'id');
}
模型项:id,container_id,type_id,名称,created_at,updated_at
public function containers()
{
return $this->belongsTo('App\Models\Containers', 'id', 'container_id');
}
如何获得属于items
的{{1}}的所有container
,而不必执行以下操作:
container:name
...并查看特定容器中的特定项目,而不必做更讨厌的事情:
//Route::get('/api/v1/containers/{container}/items', 'ItemsController@index');
public function index($container)
{
//Show all items in a specific container
return Containers::where('name', $container)
->firstOrFail()
->items()
->get()
->toJson();
}
在这种情况下,我只使用容器名称作为它的URL友好标记,并有助于阻止URL操作。
是否有一种方法-即使它是辅助的EmiratesTo关系-通过引用容器的名称来实现此目的,因此我可以执行//Route::get('/api/v1/containers/{container}/items/{item}', 'ItemsController@show');
public function show($container, $item)
{
//Show specific item in a specific container
return Containers::where('name', $container)
->firstOrFail()
->items()
->where('id', $item)
->firstOrFail()
->toJson();
}
而无需更改模型中的primaryKey字段。
答案 0 :(得分:2)
您可以通过做相反的事情(调用Item
而不是Contractor(s)
来实现这一点。看起来像这样:
$items = Item::whereHas(['container' => function($query) use ($container) {
$query->where('name', $container);
}])->get()->toJson();
::whereHas()
方法将仅返回items
,其中container
具有您指定的名称。
如果这还不够短,您可以在Item
模型上创建一个query scope,并将上面的功能移入其中:
// App\Item.php - or where the model is
public function scopeInContainer($query, $container, $id = null)
{
$query = $query->whereHas(['container' => function($q) use ($container) {
$q->where('name', $name);
}]);
if ($id) {
$query = $query->where('id', $id)->firstOrFail();
}
return $query;
}
然后使用它:
$items = Item::inContainer($container)->get()->toJson();
然后,当通过Item
调用$id
时,您只需要调用:
$item = Item::find($id);
希望这就是您想要的。