Rails 模型、视图、控制器和帮助程序: 哪里去了?

在 RubyonRails 开发(或者一般的 MVC)中,我应该遵循什么样的快速规则来放置逻辑。

请用 把这个放在这里而不是 别放那儿回答肯定的问题。

44859 次浏览

这取决于逻辑是怎么解释的。

通常,向模型中推入更多的东西是有意义的,这样控制器就变小了。这样可以确保在需要访问模型所表示的数据的任何地方都可以轻松地使用此逻辑。视图应该几乎不包含逻辑。所以,总的来说,你应该努力做到这一点,这样你就不会重复自己。

此外,快速的一点谷歌揭示了一些更具体的例子,什么去哪里。

模型: 验证需求、数据关系、创建方法、更新方法、销毁方法、查找方法(注意,你不仅应该拥有这些方法的通用版本,而且如果你正在做很多事情,比如通过姓氏查找红头发的人,那么你应该提取这个逻辑,这样你所要做的就是调用 find _ redH _ by _ name (“ smith”)或类似的东西)

视图: 这应该是关于数据的格式化,而不是数据的处理。

控制器: 这是进行数据处理的地方。来自互联网: “控制器的目的是响应用户请求的操作,获取用户设置的任何参数,处理数据,与模型交互,然后将请求的数据以最终形式传递给视图。”

希望能帮上忙。

MVC 模式实际上只关心用户界面,其他什么都不关心。您不应该在控制器中放置任何复杂的业务逻辑,因为它控制的是视图,而不是逻辑。控制器应该关注选择合适的视图,并将更复杂的内容委托给领域模型(Model)或业务层。

领域驱动设计有一个服务的概念,这是一个地方,你坚持逻辑,需要编排许多不同类型的对象,这通常意味着逻辑不属于一个模型类。

我通常认为服务层是我的应用程序的 API。我的服务层通常与我正在创建的应用程序的需求非常接近,因此服务层可以简化我的应用程序的低层中发现的更复杂的交互,也就是说,你可以绕过服务层完成同样的目标,但是你必须拉动更多的杠杆才能使它工作。

请注意,我这里不是在谈论 Rails,而是在谈论一种通用的体系结构风格,它可以解决您的特定问题。

Rails 的方法是使用 瘦瘦的控制器和胖胖的模特

车祸

Controller : 把代码放在这里,这些代码需要计算出用户想要什么,决定给他们什么,计算出他们是否登录,他们是否应该看到某些数据,等等。最后,控制器查看请求并计算出要显示哪些数据(模型)和要呈现哪些视图。如果您对代码是否应该放到控制器中存在疑问,那么它可能不应该放到控制器中。保持你的控制器 很瘦

View : 视图应该只包含显示数据(模型)的最小代码,它不应该进行大量的处理或计算,它应该显示由模型计算(或汇总)的数据,或者由控制器生成的数据。如果您的视图确实需要执行模型或控制器无法完成的处理,请将代码放在 Helper 中。View 中的大量 Ruby 代码使得页面标记很难阅读。

Model : 您的模型应该是与您的数据(组成您的站点的实体,例如用户、发布、帐户、朋友等)相关的代码所在的 所有位置。如果代码需要保存、更新或汇总与实体相关的数据,请将其放在这里。它可以在视图和控制器之间重用。

补充一下保利弗尼克的回答:

Helper : 使创建视图更容易的函数。例如,如果您总是迭代一个小部件列表来显示它们的价格,那么将其放入一个 helper (以及用于实际显示的部分)中。或者,如果您有一块 RJS,您不希望它把视图弄得乱七八糟,那么将它放到 helper 中。

在控制器中放入与授权/访问控制相关的内容。

模型都是关于你的数据。验证,关系,CRUD,业务逻辑

视图是关于显示数据的。只显示和获取输入。

控制器控制从模型到视图(以及哪个视图)以及从视图到模型的数据。控制器也可以在没有模型的情况下存在。

我喜欢把控制器想象成一个保安/接待员,他将客户(请求)引导到适当的柜台,在那里您可以向出纳员(视图)提问。然后出纳员(视图)从一个你从未见过的经理(模型)那里得到答案。然后请求返回到保安/接待员(控制器) ,并等待直到您被指示去另一个出纳员(视图) ,该出纳员(视图)告诉您经理(模型)在回答其他出纳员(视图)问题时告诉他们的答案。

同样地,如果你想告诉出纳员(视图)一些事情,那么除了第二个出纳员会告诉你经理是否接受了你的信息之外,基本上同样的事情会发生。也有可能是保安/接待员(控制员)让你走开,因为你没有权利告诉经理这些信息。

因此,为了扩展这个比喻,在我刻板和不现实的世界里,出纳员(观点)漂亮但是头脑空洞,并且经常相信你告诉他们的任何事情,保安/接待员很少有礼貌,但是他们知道人们应该去哪里,不应该去哪里,经理们真的很丑陋和刻薄,但是知道一切,并且能够分辨出什么是真什么是假。

有助于正确分离的一件事是避免“将局部变量从控制器传递到视图”反模式。而不是这样:

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController


def show
@foo = Foo.find(...)
end


end


#app/views/foos/show.html.erb:
...
<%= @foo.bar %>
...

尝试将它移动到一个可以作为 helper 方法使用的 getter:

# app/controllers/foos_controller.rb:
class FoosController < ApplicationController


helper_method :foo


def show
end


protected


def foo
@foo ||= Foo.find(...)
end


end


#app/views/foos/show.html.erb:
...
<%= foo.bar %>
...

这使得修改放入“@foo”的内容和使用方式更加容易。它增加了控制器和视图之间的分离,而不会使它们变得更复杂。

测试,测试..。 在模型中放入尽可能多的逻辑,然后您将能够正确地测试它。单元测试通过测试模型来测试数据及其形成方式,功能测试通过测试控制器来测试数据的路由或控制方式,因此,除非数据在模型中,否则不能测试数据的完整性。

J

这里已经有了完美的解释,一个非常简单的句子作为结论,并且很容易记住:

我们需要智能模型,瘦控制器,和哑巴视图。

Http://c2.com/cgi/wiki

简单来说, 模型 将包含与表相关的所有代码、它们的简单或复杂关系(将它们视为涉及多个表的 sql 查询)、操纵数据/变量以使用业务逻辑得到结果。

控制器 将有指向所请求作业的相关模型的代码/指针。

视图 将接受用户输入/交互并显示结果响应。

任何重大的偏差都会给该部分带来不必要的压力,并且整个应用程序的性能可能会受到影响。