【问题标题】:Does this piece of rails code follow MVC architecture?这段 Rails 代码是否遵循 MVC 架构?
【发布时间】:2013-05-22 10:17:01
【问题描述】:

在我看来:

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

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

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

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

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

【问题讨论】:

  • 我看不出有什么问题。您正在创建一个名称为“product_id”的下拉列表以及所有可用产品的名称和 ID 选项。
  • @satya 我的意思是我正在我的视图 Product.find(:all) 中进行查询以获取下拉列表的所有产品。
  • .. 我认为整个 Rails 并没有实现 MVC,但这可能只是 my opinion
  • 没关系,萨钦。另一种方法是在控制器中初始化产品。 (products = Product.all) 并在视图中使用@products。 “产品”应该是控制器中的实例变量。我无法在此评论中随意添加 :(

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


【解决方案1】:

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

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

在 MVC 的 Rails 版本中:

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

与所有 OOP 一样,您的里程肯定会有所不同。

【讨论】:

  • 所以你的意思是在视图中执行 Product.find(:all) 是不正确的。那么如何处理呢?
  • @SachinPrasad웃 您应该在控制器中执行搜索,并将其分配给可以传递给视图的变量。例如:@products = Product.all 一般属于控制器动作。
【解决方案2】:

这与 MVC 差不多。

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

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

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

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

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

【讨论】:

    【解决方案3】:

    (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
    

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

    【讨论】:

    • 我真的很难向 Java 开发人员解释这是一个很好的做法,我们对此表示同意。你能帮帮我吗?
    • 我认为教授基本 MVC 可能超出了这个基本问题的范围,但我建议阅读 MVC(这里是一个很好的资源:@​​987654321@),然后也许解释为什么某些零件适合它们的位置,以及它如何简化维护等。运气!
    • 我的意思是这段代码没有遵循 MVC 对吗?我们正在调用一个助手,作为回报它调用模型。是不是我们必须调用一个控制器,然后它应该调用模型?
    • 我们可以直接从视图中调用模型吗?
    • 那不遵循 MVC,不。因为“C”应该是收集数据,而视图只是应该显示已经收集的数据。将视图视为纯粹的呈现。到渲染时,您不需要获取更多数据。这就是为什么即使是助手也不是很理想的原因。因为您在视图层中仍然在获取数据。
    猜你喜欢
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 2019-09-26
    • 2019-05-18
    • 2015-03-08
    • 2021-08-26
    • 1970-01-01
    相关资源
    最近更新 更多