我想要同时正确保存两种多态关系。下面的代码有效,但我觉得它可以更清晰,因为我假设两个update()
方法两次调用数据库。
NewsModule::class
可以有不同的模块项; VideoModule
,TextModule
,ImageModule
以及其他一些内容。每个包含自己的内容都要附加到父NewsModule
。
如上所述,代码可以正常设置关系,但我确信有更清晰的方法可以同时保存两者。
我也愿意接受有关清理if
陈述的建议。但也许这是另一篇文章。
public function update(Request $request, $id)
{
$module = NewsModule::find($id);
if ($module->type === 'text') {
$content = TextModule::find($module->content_id);
} elseif ($module->type === 'image') {
$content = ImageModule::find($module->content_id);
};
$module->update($request->all());
$content->update($request->all());
return fractal()
->item($module, new NewsModuleTransformer)
->parseIncludes(['content'])
->toArray();
}
更新(按要求提供更多代码)......
结构:
news_modules
- id
- content_id
- content_type
- etc
text_modules
- id
- content
- etc
image_modules
- id
- image_id
- etc
NewsModule:
class NewsModule extends Model
{
public function content()
{
return $this->morphTo();
}
}
所有项目模块:
class TextModule extends Model
{
public function newsmodules()
{
return $this->morphMany(NewsModule::class, 'content');
}
}
答案 0 :(得分:3)
public function update(Request $request, $id)
{
$modele = NewsModule::find($id);
$module->update($request->all());
$module->content->update($request->all());
return fractal()
->item($module, new NewsModuleTransformer)
->parseIncludes(['content'])
->toArray();
}
这将总共运行4个查询。每个模块检索1个,另一个模块更新。这可以减少为3,如:
public function update(Request $request, $id)
{
$modele = NewsModule::find($id);
$module->update($request->all());
$module->content()->update($request->all());
return fractal()
->item($module, new NewsModuleTransformer)
->parseIncludes(['content'])
->toArray();
}
$module->content()->update($request->all());
的缺点是如果$request->all()
中的任何内容不是该内容模型中的列或者数组是值,则会抛出错误。您可以通过在相关模型的update()
属性(如果已定义)上调用$fillable
来避免这种情况,如:
$fillable = $module->content()->getRelated()->getFillable();
$module->content()->update($request->only($fillable));
这种方式也不会触发您拥有的任何模型事件侦听器,因为您从未从数据库中检索模型。
要更进一步,请查看Route Model Binding。在app\Providers\RouteServiceProvider
的{{1}}方法中:
boot()
这种方式“新闻”在将其用作路由参数时将始终解析为public function boot()
{
parent::boot();
Route::model('news', App\NewsModule::class);
}
的实例。所以你的路线会是这样的:
NewsModule
因此,在您的Route::match(['patch', 'put'], '/news/{news}', 'NewsController@update');
方法中,只需在方法中键入提示即可解析模型:
update