使用与子弹而不是关联ID的belongsTo雄辩的关系

时间:2019-05-22 14:57:00

标签: php laravel eloquent

给出以下两个表和关系:

模型容器: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字段。

1 个答案:

答案 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);

希望这就是您想要的。