0

在我看来:

  <%= f.collection_select :product_id, Product.find(:all), :id, :name %>

Product.find(:all)在上面的代码中指的是。

或者在某些情况下,我们在模型中定义一个函数并在视图中调用它:ModelName.my_function

如果不 !在不违反 MVC 原则的情况下,最好的方法是什么?

我的意思是它是我们可以遵循的最好的架构还是我们有别的东西?

4

3 回答 3

2

The View Shouldn't (Generally) Talk to a Model Directly

As a rule of thumb, the view should not be directly communicating with a model. There are probably times that violating this principle makes sense, but without more context I would assume that this isn't one of them.

In the Rails version of MVC:

  1. The model should define behavior.
  2. The controller should assign models and collections to instance variables which are then passed to the view.
  3. The view should format the attributes of the model as passed in from the controller as instance variables.
  4. In some cases, calling methods on objects passed in from the controller is warranted (not everything needs to be pre-computed into variables by the controller) but the view should not invoke the model directly.

As with all things OOP, your mileage may certainly vary.

于 2013-05-22T14:21:41.503 回答
1

( V )iew 不应该直接与 ( M ) 模型对话,这就是它Product.find(:all)正在做的事情。理想情况下,您想要做的是将局部变量从您的控制器传递到您的视图中。

尽管这是教条上正确的方法,但有时通过局部变量传递每个最后一个变量是不切实际的。在这些情况下,您可能应该考虑创建一个助手来代替它。这样它就可以有更多的语义含义:

 <%= f.collection_select :product_id, Product.find(:all), :id, :name %>

变成

 <%= f.collection_select :product_id, product_options_for_select, :id, :name %>

并且您有一个关联的助手,看起来像这样:

def product_options_for_select
  Product.find(:all)
end

这使得它至少更易于维护,特别是如果您重用它,以防您将来需要返回不同的子集。

于 2013-05-22T14:54:39.587 回答
1

这与它所获得的 MVC 差不多。

在这个简单案例中,控制器的作用是使正确的模型可用于正确的视图(中介)。多亏了 Rails,您实际上不必为此编写任何控制器代码。这就是 Rails MVC 框架的重点——从您的应用程序中消除平凡的样板模式实现。

从语义上讲,在视图中使用 Products.find(:all) 并在控制器中分配 @products = Products.find(:all) 然后在视图中引用 @products 是一回事,但是为什么要故意选择需要更多代码?(如果您需要稍后重构,这很容易,但不要过早重构,否则您最终会遇到麻烦)。

而且,Rails 将缓存查询(在请求的整个生命周期内),因此即使您在同一个视图中多次使用 Products.find(:all) ,它也不会对性能产生任何影响。

如果您要限定查询范围,您可以在模型中执行此操作,并且再次,您不需要任何控制器代码。

什么时候需要控制器代码?可能是为了执行授权或某些特定于域的逻辑,或者您需要使用另一种(不是 HTML)格式(例如 JSON)来响应。

于 2013-05-22T14:01:07.070 回答