我正在构建我的API(品牌和型号),我希望拥有嵌套资源(不确定这是否正确)。
/使/法拉利/模型 /使/法拉利/模型/ F40
我定义了以下路线
Route::resource('makes.models', 'ModelsController');
和ModelsController.php
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$data = Models::all();
return response()->json($data);
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$data = Models::find($id);
return response()->json($data);
}
和模型模型(是的,我需要更改名称)
class Models extends Model
{
public function make()
{
return $this->belongsTo('App\Make');
}
}
我的问题是,即使路线有效,它也会返回数据库中的所有模型(不仅仅是法拉利),我应该在哪里定义这种关系?不是自动的吗? 我有2个表make(id,name),models(id,name,make_id)
谢谢你!答案 0 :(得分:1)
资源路由将定义以下路由:
Method Path Action
GET /makes/{make}/models index
GET /makes/{make}/models/create create
POST /makes/{make}/models store
GET /makes/{make}/models/{id} show
GET /makes/{make}/models/{id}/edit edit
PUT /makes/{make}/models/{id} update
DELETE /makes/{make}/models/{id} destroy
您的请求/品牌/法拉利/型号与这些路线中的任何一条都不匹配(因为您的show参数只接受一个参数)。您可以请求/ makes / models / 1来调用show,但实际上您缺少此路由,因为嵌套路由不提供它。
如果你说你总是得到所有项目,你很可能会点击索引动作而不是显示。
如果您想使用/ makes / ferrari / models / f40查询模型,您需要这样的路线:
Route::get('/makes/{make}/model/{model}', 'ModelsController@show');
这已经是为您创建的资源路径的一部分。 现在,在show controller中,使用make和model参数来查找正确的数据集:
public function show($make, $model)
{
$data = Model::with('makes')
->whereName($model)
->whereHas('makes', function ($query) use ($make) {
$query->where('name', '=', $make);
})->get();
return response()->json($data);
}
Laravel不会自动为你做这件事。
您可能需要查看https://laravel.com/docs/5.3/routing#route-model-binding以了解更为复杂的方法。您可以在两个模型中设置路线密钥名称,覆盖getRouteKeyName()
方法并返回' name'在这种情况下,告诉Laravel使用name列而不是id。
您还可以通过执行类似
的操作将路径中的参数专门绑定到自定义分辨率逻辑$router->bind('model', function ($value) {
return Model::where('name', $value)->first();
});
然后每次在路线中使用{model}
时,都会使用名称而不是ID。
但是,请注意,您必须确保存储在数据库中的model和make的名称已经过时,以便它们适合在URL中使用。如有必要,您可以在绑定中执行此操作,如上所示,返回
return str_slug(Model::where('name', $value)->first());
然而,这是未经测试的,因此可能会或可能不会。
希望有所帮助: - )
答案 1 :(得分:0)
使用嵌套资源时,所有控制器操作都将收到额外的第一个参数(父资源标识符)。因此,您需要相应地更新控制器操作:
public index($make) {
$make = Make::with('models')->where('name', $make)->firstOrFail();
return view('models.index', compact('make'));
}
public show($make, $model) {
$make = Make::with('models')
->where('name', $make)
->firstOrFail();
$model = $make->models()
->where('name', $make)
->firstOrFail();
return view('models.show', compact('make', 'model'));
}
它应与您的其他控制器操作相同。
请注意,我对数据库的结构做了假设。