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 %>
精彩评论