【问题标题】:Laravel: One Controller for multiple ModelsLaravel:一个控制器用于多个模型
【发布时间】:2016-12-02 16:33:30
【问题描述】:

我目前正在使用 Laravel 重建我的 vanilla-PHP-App,但遇到以下问题。 我有多个数据库表,代表单词类别(名词,动词,副词,...)。对于每个表,我创建了一个单独的模型、一个 route::resource 和一个单独的资源控制器。例如:

NomenController.php

public function show($id)
{
    $vocab = Nomen::find($id);
    return view('glossarium.vocab_update', compact('vocab'));
}

和

动词控制器.php

public function show($id)
{
    $vocab = Verb::find($id);
    return view('glossarium.vocab_update', compact('vocab'));
}

...除了 Model 类之外,它们本质上是相同的。

我不想为每个模型创建一个单独的控制器,这完全一样。解决这个问题的最简单和优雅的方法是什么? 我是否应该只创建一个 VocabController.php 并为模型名称添加一个参数,例如:

Route::resource('/vocab/{category}', 'VocabController');

然后在这个控制器中添加一个构造方法

public function __construct ($category) {
    if ($category == 'nomen') {
        $this->vocab = App\Nomen;
    }
    else if ($category == 'verb') {
         $this->vocab = App\Verb;
    }
}

我想知道是否有更简单的方法可以做到这一点。我可以通过路由模型绑定以某种方式做到这一点吗?

提前致谢

【问题讨论】:

  • 你建议的方式可行,但我建议创建一个名词/动词/等继承自的“词汇”模型,然后你只需要你的词汇控制器。

标签: php laravel model-view-controller


【解决方案1】:

只需在 App\Traits 中创建一个像这样的trait,(你可以给它起任何名字......不过不要和我一起去......我觉得它很蹩脚...... :P)

namespace App\Traits;

trait CommonControllerFunctions {

    public function show($id) {
        $modelObject = $this->model;

        $model = $modelObject::find($id);

        return view('glossarium.vocab_update', compact('model'));
    }

}

在您的 NomenController 和 VerbController 中,执行以下操作:

use App\Traits\CommonControllerFunctions;

class NomenController {

    use CommonControllerFunctions;

    protected $model = Nomen::class;

}

和

use App\Traits\CommonControllerFunctions;

class VerbController {

    use CommonControllerFunctions;

    protected $model = Verb::class;

}

注意:请注意,此示例仅适用于您的特定情况...每个人的代码实践方式不同,因此此方法可能不会得到所有人的认可... p>

【讨论】:

  • 谢谢!我将阅读更多关于特质的内容,然后尝试并发布。
  • 这个解决方案仍然不能解决路由器的问题。开发人员仍然必须创建 2 条路线。对两个相同的控制器使用特征并不是最简单的解决方案;-)
  • @piotr 实际上,每个资源路由应该只适用于一个控制器。将所有东西都放在一个控制器中是一种错误的做法。如果有一天一个单独的字段被添加到说“动词”表......那么必须制作一个新的控制器以及一个新的路线(无论如何),并且必须重复所有步骤......因此,这是一个结构化代码的无效实践,我本人不赞成这种编码实践,这就是我在答案中写最后一行的原因。我们代码中的每个函数都必须遵循单一职责规则。
  • 你是对的,但 Bene 想要尽可能简单的解决方案
  • @piotr 很简单。无效就不行。我对你的回答没有任何问题。我只是分享了我认为有效/真实的内容。就个人而言,我永远不会遵循 Bene 的方法。这不是我们遵循模块化结构的方式。每个控制器都必须有自己的视图,自己的模式。编码应该以这样一种方式完成,即将来添加任何额外内容不会导致代码中的重大更改。
【解决方案2】:

我认为最简单的方法是只创建一个控制器,例如 VocabController 和 nomen、verb 以及任何你想要的方法。

路线:

Route::get('/vocab/nomen/{nomen}', 'VocabController@item');
Route::get('/vocab/verb/{verb}', 'VocabController@item');

和模型绑定:

Route::model('nomen', 'App\Nomen');
Route::model('verb', 'App\Varb');

那么你的方法应该是这样的:

public function item($item)
{
    return view('glossarium.vocab_update', $item);
}

请记住,$item 已从数据库中获取模型。

【讨论】:

  • 嗯,看起来很有趣。如果我对每个数据库表都有一个控制器方法,那么我是否需要单独的 CRUD 操作方法,如公共函数 verb_create、....公共函数 verb_delete、nomen_create、nomen_delete 等......?还是我只需要为每个请求编写不同的路由(如 PUT、DELETE 等)?
  • 我觉得分开的路线比较好
猜你喜欢
  • 1970-01-01
  • 2014-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多