Rails,将复杂的逻辑拉出视图

时间:2013-11-01 15:13:14

标签: ruby-on-rails

我有一个复杂的观点,我想知道我应该做这个与众不同的观点吗?图片(或代码)值1000字,所以继续观看......

    <% @orientation_by_date[date].each do |orientation| %>
      <% if current_user %>
        <% if orientation.active? %>
          <li><%= link_to orientation.class_time, new_orientation_registration_path(orientation) %>
              (<%= orientation.current_number_seats %>/<%= orientation.seats %>)</li>
        <% else %>
          <li><%= orientation.class_time %>(Class full)</li>
        <% end %>
        <%= link_to "VIEW", orientation_registrations_path(orientation) %></li>
      <% else %>
        <% if orientation.active? %>
          <li><%= link_to orientation.class_time, new_orientation_registration_path(orientation) %>
              (<%= orientation.current_number_seats %>/<%= orientation.seats %>)</li>
        <% elsif orientation.class_date.before Date.today %>
          <li><%= orientation.class_time %>(Class Closed)</li>
        <% end %>
        <% else %>
          <li><%= orientation.class_time %>(Class full)</li>
        <% end %>
      <% end %>
    <% end %>

您正在查看的是计划应用程序的前端日历视图。根据不同的状态,您可以在日历上看到每天不同的信息,即剩余的座位数,而“完全等级”与管理员的其他信息相比。我应该以某种方式将这种逻辑拉入我的模型或控制器吗?

2 个答案:

答案 0 :(得分:0)

有许多方法可以给猫皮肤。哪个'正确'与个人偏好一样多。也就是说,这里有一些您可能想要考虑的想法。

为每种类型的用户使用部分 这可能是或可能不是您的驾驶问题,但决策的最外层是基于用户类型,因此为每种类型的用户构建部分可能是有意义的。在这种情况下,您可能有'active_user_orientation_view'和'guest_orientation_view'。这样做可以将您的视图(此部分)减少到单个if-then-else语句,并清楚地表明您的意图 - 注册用户会看到一件事,而客人会看到其他内容。

将重复代码包装到辅助方法中 使用完全相同的代码生成两个列表项。让它干!举个例子,我可能会进入OrientationsHelper(app / helpers / orientations_helper.rb)并添加一个像这样的#orientation_full_item助手

def orientation_full_item(orientation)
  content_tag(:li) do
    "#{orientation.class_time} (Class full)"
  end
end

使用该助手,呈现“类已满”消息的两行可以减少到&lt;%= orientation_full_item(orientation)%&gt;。您可以对提供注册表单链接的列表项执行相同操作。为了保持一致性,您可以对所有列表项执行此操作。这会给你一个非常清楚地表明其意图的观点。

考虑使用演示者 与使用面向视图的便捷方法丢弃模型(业务逻辑)不同,更好的选择是创建一个接受类实例并提供相同方便方法的新类。这就是Presenter模式的全部内容。它的优点是你可以非常清楚地按照它的意图组织你的代码 - 商业逻辑保持在一起并保持与视图逻辑的联系。在这种情况下,您可以提供一个ActiveUserOrientationPresenter和一个GuestOrientationPresenter类,每个类都提供一个#list_item方便方法,能够使用适当的内容呈现列表项。

PragProg的家伙有一个由布鲁斯威廉姆斯写的标题,并提出了一些关于如何构建强大的视图代码的好建议,这些代码可能值得投入资金和时间。其中一个可用的代码段专门处理演示者。你可以阅读它http://media.pragprog.com/titles/warv/present.pdf

答案 1 :(得分:-1)

编写单元测试,用XPath确定所有<li>项的内容。

抓住Nokogiri,并使用Nokogiri::HTML::Builder在Ruby中编写所有内容:

builder = Nokogiri::HTML::Builder.new do |doc|
   doc.ul {
     doc.li('data 1')
     doc.li('data 2') if oodles_of_poodles?
     doc.li('data 3')
   }
end

puts builder.to_html

现在它只使用一种语言,你可以自由地重构它,而不必经常绊倒将两种语言混合在一起所需的转义标记。