这段rails代码是否遵循MVC架构?

时间:2013-05-22 10:17:02

标签: ruby-on-rails ruby-on-rails-3 model-view-controller

在我的观点中:

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

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

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

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

我的意思是它是我们可以遵循的最佳架构还是我们还有其他东西?

3 个答案:

答案 0 :(得分:2)

视图不应(通常)直接与模型对话

根据经验,视图不应直接与模型通信。有时候违反这一原则是有道理的,但如果没有更多的背景,我会认为这不是其中之一。

在MVC的Rails版本中:

  1. 模型应该定义行为。
  2. 控制器应该将模型和集合分配给实例变量,然后传递给视图。
  3. 视图应格式化从控制器传入的模型属性作为实例变量。
  4. 在某些情况下,保证从控制器传入的对象的调用方法(并非所有内容都需要由控制器预先计算为变量),但视图直接调用模型。
  5. 与OOP一样,你的里程肯定会有所不同。

答案 1 :(得分:1)

这就像MVC一样。

在这种简单的情况下,控制器的作用是使正确的模型可用于正确的视图(中介)。感谢Rails,您不必实际编写任何控制器代码。这就是Rails MVC框架的重点 - 从您的应用程序中消除平凡的样板模式实现。

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

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

如果您要查询范围,可以在模型中执行此操作,同样,您不需要任何控制器代码。

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

答案 2 :(得分:1)

V )iew不应直接与( M )odel对话,这是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

这使得它至少可以维护一些,特别是如果你重复使用它,以防你将来需要返回一个不同的子集。