如何在视图文件中管理if-then爆炸?

时间:2011-02-16 23:55:01

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

如果这不遵循良好的问题指南,我会道歉,但我希望它在How to Manage CSS Explosion的课堂上表现良好并得到同样有用的回复。

我熟悉一些基本的视图冗长缓解策略,如下所示:

  • 在适当的地方使用帮助
  • 不要重复自己
  • 使用部分和布局

如果我在上面的列表中遗漏了一些重要的想法,请随意提出建议。

尽管如此,我仍然认为在我看来有几个维度/自由度,导致很多if-then语句或至少三元块。例如,在我正在搞乱的事情中,我正在为一个程序的标题栏工作,当三个“大”变量调用视图时:

  • 用户是否为admin
  • 用户是否已登录
  • 正在查看的网页是属于用户还是其他人

最终看起来像这个烂摊子:

<% content_for :subheader do %>
  <div class="row">
    <% if @user %>
      <% if @user == current_user %>
        <%= link_to 'My programs', user_programs_path(current_user), :class => 'active' %>
      <% else %>
        <%= link_to "#{@user.username}'s programs", user_programs_path(@user), :class => 'active' %>
      <% end %>
      <%= link_to 'Browse all programs', programs_path %>
    <% else %>
      <% if current_user %>
        <%= link_to 'My programs', user_programs_path(current_user) %>
      <% end %>
      <%= link_to 'Browse all programs', programs_path, :class => 'active' %>
    <% end %>
    <%= link_to 'New Program', new_program_path, :class => 'admin' if current_user.admin? %>
  </div>
  <% if @regions %>
    <div class="row second">
      <%= link_to 'Regional program search', request.fullpath, :class => 'active' %>
    </div>
  <% end %>
<% end %>

难看。可读且易于访问,但很难看。一些建议?

在经验和LESS之类的新技术之间,我已经非常擅长减少我的CSS文件,但我仍然遇到了MVC视图的爆炸问题。

2 个答案:

答案 0 :(得分:6)

我会使用帮助器和模型定义来干掉你的代码:

class User
  def possesive
    self == current_user ? 'My' : "#{username}'s"
  end
end

module ...Helper
  def user_program_link user
    if user
      link_to "#{user.possesive} programs", user_programs_path(user), :class => 'active'
    elsif current_user
      link_to 'My programs', user_programs_path(current_user)
    end
  end
end

然后,您可以简化user_program_path调用的所有if语句:

<%= user_program_link @user %>

这会将您的观看代码缩减为:

<% content_for :subheader do %>
  <div class="row">
    <%= user_program_link @user %>
    <% if @user %>
      <%= link_to 'Browse all programs', programs_path %>
    <% else %>
      <%= link_to 'Browse all programs', programs_path, :class => 'active' %>
    <% end %>
    <%= link_to 'New Program', new_program_path, :class => 'admin' if current_user.admin? %>
  </div>
  <% if @regions %>
    <div class="row second">
      <%= link_to 'Regional program search', request.fullpath, :class => 'active' %>
    </div>
  <% end %>
<% end %>

继续此过程以干掉其余代码。

答案 1 :(得分:0)

重写视图代码如下:

<% content_for :subheader do %>
  <div class="row">
    <% if @user ||  current_user %>      
      <%= link_to ((current_user == @user or @user.nil?) ? "My programs" : 
                    "#{@user.username}'s programs"), 
                  user_programs_path(@user || current_user), 
                  :class => 'active' %>
    <% end %>
    <%= link_to 'Browse all programs', programs_path, 
          :class => (@user ? '' : 'active') %>
    <%= link_to 'New Program', new_program_path, :class => 'admin' if current_user.admin? %>
  </div>
  <% if @regions %>
    <div class="row second">
      <%= link_to 'Regional program search', request.fullpath, :class => 'active' %>
    </div>
  <% end %>
<% end %>