如何使视图更简单,控制器更有用?

时间:2010-06-29 19:32:36

标签: ruby-on-rails model-view-controller variables controller nested

这个问题涉及清理视图并为控制器提供更多工作。

我的项目中有很多案例,我在视图中显示了嵌套变量。例如:

# controller
@customers = Customer.find_all_by_active(true)
render :layout => 'forms'

# view
<% @customers.each do |c| %>
  <%= c.name %>
  <% @orders = c.orders %>  # I often end up defining nested variables inside the view
    <% @orders.each do |o| %>
    ...
    <% end %>
<% end %>

我对RoR很新,但似乎我在这里所做的与'智能控制器,愚蠢的观点'的心态不一致。我有很多客户,每个客户都有很多订单,如何在我的控制器内正确定义这些变量,然后在视图中访问它们?

如果您可以提供控制器外观的示例,然后我将如何与视图中的内容相关联,那将非常有用。非常感谢你!

3 个答案:

答案 0 :(得分:2)

我认为你所做的事情没有任何严重错误。循环遍及客户并输出他们的一些属性和每个客户,循环他们的订单并输出一些属性是一个非常注重视图的操作。

在MVC架构中,控制器负责与模型交互,选择视图和(当然在Rails的情况下)为视图提供渲染模型所需的信息。

您可以考虑将代码提取到视图助手中,如果您有多次重复的确切代码。您甚至可以对其进行泛化,传递模型和关联的名称。我没有测试过,但你应该可以这样做:

def display_attributes(models, association, attribute, association_attribute)
  content = ''
  models.each do |m|
    content << "<p>#{m.attribute}</p>"
    associated_models = m.association
    associated_models.each do |am|
      content << "<p>#{am.association_attribute}</p>"
    end
  end
  content
end

然后在视图中,你可以像这样使用帮助器:

<%= display_attributes(@customers, orders, name, name) %>

显然,您可以更改帮助程序方法中的HTML标记以满足您的要求。请注意,如果您不使用Rails 3,那么您将需要在helper方法中转义属性名称的输出。

答案 1 :(得分:2)

我认为您的代码没有任何问题。我建议您在查找中使用:include

@customers = Customer.find_all_by_active(true, :include => :orders)

减少查询次数。

答案 2 :(得分:0)

我看到你所展示的代码没有错。

你对“智能控制器,哑视图”方法感到喜忧参半,我倾向于选择"skinny controller, fat model",所以确实视图应该是愚蠢的,但你把智能放在你的模型中,你的助手(或使用演示者),但绝对不在控制器中。