开发者

loop in templates

My template looks like:

  <h2>Oracle</h2>

  <% @q_oracle.each do |q| %>
    <%= link_to(q.title + ' (' + q.answer_count.to_s + '开发者_JAVA百科) ' + q.question_id.to_s, 'http://stackoverflow.com/' + q.question_answers_url) %>  </br>

  <% end %>


  <h2>Ruby and Rails</h2>

  <% @q_ruby.each do |q| %>
    <%= link_to(q.title + ' (' + q.answer_count.to_s + ') ' + q.question_id.to_s, 'http://stackoverflow.com/' + q.question_answers_url) %>  </br>

  <% end %>

So the temlate consists the static titles (h2) and loops through the array. I am searching the way to avoid copy-paste code in the my template. Something like:

@hash = { 'Oracle' => @q_oracle, 'Ruby and Rails' => @q_ruby }

@hash.each { |@t, @a|

  <h2>@t</h2>

  <% @a.each do |q| %>
    <%= link_to(q.title + ' (' + q.answer_count.to_s + ') ' + q.question_id.to_s, 'http://stackoverflow.com/' + q.question_answers_url) %>  </br>

  <% end %>
}

Is it possible?


Yes you can do it.

Ruby 1.9 solution

In Ruby 1.8 this solution can be used when titles order doesn't matter. In Ruby 1.9 titles would appear in order they were inserted in hash.

Just place this variable to your controller action:

@hash = { 'Oracle' => @q_oracle, 'Ruby and Rails' => @q_ruby }

And access this variable from your view:

<% @hash.each do |t, a| %>
  <h2><%= t %></h2>
  <% a.each do |q| %>
    <%= link_to(q.title + ' (' + q.answer_count.to_s + ') ' + q.question_id.to_s, 'http://stackoverflow.com/' + q.question_answers_url) %>  </br>
  <% end %>
<% end %>

Ruby 1.8 with sorted keys

This method sorts keys so they appear in alphabetical order.

<% @hash.keys.sort.each do |t| %>
  <h2><%= t %></h2>
  <% @hash[t].each do |q| %>
    <%= link_to(q.title + ' (' + q.answer_count.to_s + ') ' + q.question_id.to_s, 'http://stackoverflow.com/' + q.question_answers_url) %>  </br>
  <% end %>
<% end %>

Ruby 1.8 with arrays

This method would behave like Ruby 1.9 in any ruby version - titles would appear in order they were added.

Variable @hash must be initialized as:

@hash = [ ['Oracle', @q_oracle], ['Ruby and Rails',@q_ruby] ]

View must be updated to:

<% @hash.each do |title_with_questions| %>
  <h2><%= title_with_questions[0] %></h2>
  <% title_with_questions[1].each do |q| %>
    <%= link_to(q.title + ' (' + q.answer_count.to_s + ') ' + q.question_id.to_s, 'http://stackoverflow.com/' + q.question_answers_url) %>  </br>
  <% end %>
<% end %>


It's certainly possible, but it's putting an awful lot of Ruby logic in a view, which is kind of smelly. I think it would be better to factor out duplicated the question-list body portion into a partial.

Main view...

<h2>Oracle</h2>

<%= render :partial => 'question_list', :locals => {:questions => @q_oracle} %>


<h2>Ruby and Rails</h2>

<%= render :partial => 'question_list', :locals => {:questions => @q_ruby} %>

Partial: _question_list.html.erb ...

  <% questions.each do |q| %>
    <%= link_to(q.title + ' (' + q.answer_count.to_s + ') ' + q.question_id.to_s, 'http://stackoverflow.com/' + q.question_answers_url) %>  </br>

  <% end %>

This approach is more readable than the nested loop, and it's also more flexible in terms of customizing the page structure. For instance: what if you want to apply different styling to each list, or place a divider in between?


But of course it's possible to loop through an Hash.

<% @hash.each do |title, var|
  <h2><%= title %></h2>
  ... so forth ...
<% end %>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜