如何使这个ruby视图代码更具可读性和干燥性?

时间:2011-10-19 15:40:11

标签: ruby haml

我在sinatra应用程序中遇到了相当复杂的视图。你会如何重构这个混乱?

.central
  %ul
    %li
      - selected = is_sub ? "": "selected"
      %a{:href => '/' + section + '/index.html', :class => selected}
        1
    -navigation.each_index do |primary_idx|
      -primary_hash  = navigation[primary_idx]
      -primary_token = primary_hash[:rewrite] || convert_to_url_token(primary_hash[:title])
      -if url_match?(primary_token)
        -primary_hash[:children].each_with_index do |secondary_hash, secondary_idx|
          %li
            -secondary_token = secondary_hash[:rewrite] || convert_to_url_token(secondary_hash[:title])
            %a{:href => '/' + section + '/' + secondary_token + '/index.html', :class => url_match?(secondary_token) ? "selected" : ""}
              =secondary_idx + 2
%p
  -navigation.each_index do |primary_idx|
    -primary_hash  = navigation[primary_idx]
    -primary_token = primary_hash[:rewrite] || convert_to_url_token(primary_hash[:title])
    -if url_match?(primary_token)
      -primary_hash[:children].each_with_index do |secondary_hash, secondary_idx|
        -secondary_token = secondary_hash[:rewrite] || convert_to_url_token(secondary_hash[:title])
        -if url_match?(secondary_token) || !is_sub
          page
          -current_page = is_sub ? secondary_idx + 2 : 1
          =current_page
          \/
          =primary_hash[:children].size + 1
          -break

2 个答案:

答案 0 :(得分:1)

很多事情:

  • navigation.each_index应该成为navigation.each。你没有单独使用索引。
  • primary_token应该被定义为navigation模型上的一种方法,因此您不会使视图混乱。同样可能来自if url_match?块。
  • 在Rails中,你可以将一些循环重构为部分。我不知道Sinatra是否支持类似的东西。
  • selectedcurrent_page内容可能应该在控制器中设置,但我对你的逻辑流程还不够了解。

基本上,您的视图应该通过控制器中设置的变量或通过对这些变量的简单方法调用(即类似variable.some_property,而不是您在这里的怪物)获取所需的所有数据。这通常意味着您必须在模型上编写更多方法来支持这一点。

答案 1 :(得分:0)

我不确定这段代码试图完成什么,因为我不清楚任何变量的设置。我认为它正试图做多级导航。这是我可能做的一些重构,以实现 目标。

视图

- section_selected = is_sub? ? "": "selected"
.central
  %ul
    %li= link_to section.name, "/#{section.url}/index.html", :class => section_selected

    - section.subsections.each do |subsection_item|
      - subsection_selected = url_match? subsection.url
      %li= link_to subsection.name, "/#{section.url}/#{subsection.url}/index.html", :class => subsection_selected

演示者课程开始

class Section
  attr_accessible :name, :url, :subsections
end

某些控制器/型号

sections = [].tap do |s|
  s << Section.new(:name => "foo", :url => "bar")
  s << Section.new(:name => "x", 
                   :url => y, 
                   :subsections => [
                                    Section.new(:name => "sub", :url => "omg")
                                   ])
end