我应该在 Laravel MVC 中的哪里保存模型?

Posted

技术标签:

【中文标题】我应该在 Laravel MVC 中的哪里保存模型?【英文标题】:Where should I be saving a model in Laravel MVC? 【发布时间】:2018-08-06 09:31:24 【问题描述】:

我试图更具体地了解 MVC 并尽可能保持控制器层的薄。

我一直问自己的一件事是“我应该在哪里调用 modelname->save()?”

查看 Laravel 文档,他们将数据设置到模型并在控制器中调用 save 似乎不正确...

<?php

namespace App\Http\Controllers;

use App\Flight;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class FlightController extends Controller

    public function store(Request $request)
    
        // Validate the request...

        $flight = new Flight;

        $flight->name = $request->name;

        $flight->save();
    

这是一个非常简单的示例,这可能就是他们在控制器中执行所有操作的原因。

根据我的理解和我一直在阅读的所有内容,所有业务逻辑都应该位于模型内部,控制器负责视图和模型之间的“流量控制”。

那么我会在模型本身内部调用 save 吗?还是我应该使用服务层?


这是我当前的示例数据问题。

我正在更新模型的状态。该行已存在于数据库中。我使用 PATCH /route/ 来访问控制器方法。从那里我得到模型。

class TimecardController extends Controller 
...
    public function markAsPass(Request $request, $id) 
        $test = Test::findOrFail($id);

        //I don't think this is the corect way  
        //$test->status = "passed";
        //$test->markedBy = "Teacher123";
        //$test->save();


        $test->passed();
        ...
        return redirect($redirect_url);
    


class Test extends Model 
...
    public function passed() 
        $this->status = "passed";

        //would I call save here? 
        //$this->save();
    

我是否采用上述方法?还是创建一个服务层,在其中使用模型实例调用模型函数,然后在模型上调用 save?

//in service class
public function makeTestAsPassed($test)
    $test->passed();
    $test->save();


如果需要任何说明,请告诉我。

【问题讨论】:

使用 setter 并调用 save 不是业务逻辑。 save的实现就是业务逻辑。 这是一个很好的问题,但也完全不适合 ***。关于这个话题有很多不同的意见,这并不是一个只有一个特定正确答案的问题。 @JoelHinz 你认为我应该在哪里发布这样的问题?我觉得应该就正确的方法达成共识。 @Devon 所以设置模型值并保存在控制器方法中是一种好的做法吗? 我想是的。有些人可能决定使用 Repository 模式不让您的应用程序依赖于 Eloquent,但除此之外,使用 save() 或 create() 是您应该从控制器执行的操作,仅此而已。 【参考方案1】:

您说得对,业务逻辑属于模型。如果您对应用程序采取“资源丰富”的方法(即围绕实体创建控制器),那么您会发现您的控制器操作很少调用多个模型方法。

您可以在模型上调用create()update() 方法,而不是调用save()。在您的 store() 控制器操作中,您可以使用这样的一行创建一个新实体:

public function store(CreateRequest $request)

    $model = Model::create($request->all());

并在 update() 操作中更新现有模型,如下所示:

public function update(UpdateRequest $request, Model $model)

    $model->update($request->all());

当涉及到业务逻辑时,您也可以在模型上调用 other 方法。要使用资源丰富的控制器,您不必必须拥有与数据库表相关的模型。

接受运送订单。大多数人会很想将ship() 方法放在OrderController 中,但是当您发送订单时会发生什么?运送订单会导致什么实体?好吧,您将创建一个 shipment,因此它可以是 OrderShipmentController 上的 store() 方法。这个store() 方法可以在你的Order 模型上调用ship() 方法:

class OrderShipmentController extends Controller

    public function store(ShipOrderRequest $request, Order $order)
    
        $order->ship();
    

如您所见,使用资源丰富的控制器和route–model binding,您可以拥有“瘦控制器”,并将应用程序的业务逻辑置于模型中。

【讨论】:

【参考方案2】:

MVC 旨在便于维护。 您不认为“好”的方法是正确的方法。所有与业务逻辑相关的数据处理都在控制器中。否则,其他编码员会因为在控制器代码中找不到数据操作逻辑而感到困惑。

您的瘦控制器目标打败了 MVC。

另请注意,模型代码旨在精简,因为它是将数据库架构定义为数据库表的镜像的地方。

MVC 不是面向对象的抽象。 MVC 是一种代码维护一致性的结构。

【讨论】:

模型是MVC中业务逻辑所在。控制器是传输层 HTTP 控制器应该接受一个 HTTP 请求,将数据传入或传出模型,然后返回一个 HTTP 响应。 还请注意,模型代码旨在精简,因为它是将数据库模式定义为数据库表的镜像的地方。 不。模型旨在建模一个对象,而objectsthings。对象所做的那些事情就是它的业务逻辑,并且应该存在于模型类的方法中。

以上是关于我应该在 Laravel MVC 中的哪里保存模型?的主要内容,如果未能解决你的问题,请参考以下文章

在 MVC 中,我在哪里放置数据库查询?

我在哪里把自定义代码放在 Laravel

MVC:我应该在哪里格式化数据?

我应该从 MVC 框架中的控制器或模型中调用 redirect() 吗?

了解 MVC 中的 ORM 模型

Eclipse RCP:我应该将模型对象保存在哪里以及它们如何与视图对话?