[英]Saving both polymorphic relationships at the same time in Laravel 5.3
我想同時正確保存兩個多態關系。 下面的代碼有效,但是我認為這可能會更清潔,因為我假設兩個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
新聞模塊:
class NewsModule extends Model
{
public function content()
{
return $this->morphTo();
}
}
所有項目模塊:
class TextModule extends Model
{
public function newsmodules()
{
return $this->morphMany(NewsModule::class, 'content');
}
}
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個查詢。 每個模塊取一個,另一個更新。 可以減少到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());
的缺點$module->content()->update($request->all());
如果$request->all()
中的任何內容不是該內容模型中的列,或者有一個數組作為值,則會引發錯誤。 您可以通過在相關模型的$fillable
屬性(如果已定義)上調用update()
來避免這種情況:
$fillable = $module->content()->getRelated()->getFillable();
$module->content()->update($request->only($fillable));
這種方式也不會觸發您擁有的任何模型事件監聽器,因為您永遠不會從數據庫中檢索模型。
要使所有步驟更進一步,請查看Route Model Binding 。 在您的app\\Providers\\RouteServiceProvider
的boot()
方法中:
public function boot()
{
parent::boot();
Route::model('news', App\NewsModule::class);
}
這樣,將“ news” NewsModule
的實例時,始終將其解析為路由參數。 因此,您的路線將類似於:
Route::match(['patch', 'put'], '/news/{news}', 'NewsController@update');
因此,在您的update
方法中,您可以通過在允許您執行的方法中鍵入提示來解析模型:
public function update(Request $request, NewsModule $news)
{
$news->update($request->all());
$news->content->update($request->all());
return fractal()
->item($news, new NewsModuleTransformer)
->parseIncludes(['content'])
->toArray();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.