在Laravel 5.3中同时保存多态关系

时间:2017-01-17 17:39:45

标签: php laravel laravel-5 eloquent polymorphism

我想要同时正确保存两种多态关系。下面的代码有效,但我觉得它可以更清晰,因为我假设两个update()方法两次调用数据库。

NewsModule::class可以有不同的模块项; VideoModuleTextModuleImageModule以及其他一些内容。每个包含自己的内容都要附加到父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');
    }
}

1 个答案:

答案 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
相关问题