Цикл в шаблонах
Мой шаблон выглядит так:
<h2>Oracle</h2>
<% @q_oracle.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 %>
<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 %>
Итак, temlate состоит из статических заголовков (h2) и циклически проходит через массив. Я ищу способ избежать копирования кода в моем шаблоне. Что-то вроде:
@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 %>
}
Возможно ли это?
Ответы
Ответ 1
Да, вы можете это сделать.
Решение Ruby 1.9
В Ruby 1.8 это решение может использоваться, когда порядок титров не имеет значения. В Ruby 1,9 названия появятся для того, чтобы они были вставлены в хэш.
Просто поместите эту переменную в действие вашего контроллера:
@hash = { 'Oracle' => @q_oracle, 'Ruby and Rails' => @q_ruby }
И получить доступ к этой переменной из вашего представления:
<% @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 с отсортированными клавишами
Этот метод сортирует ключи, чтобы они отображались в алфавитном порядке.
<% @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 с массивами
Этот метод будет вести себя как Ruby 1.9 в любой рубиновой версии - появятся заголовки, чтобы они были добавлены.
Переменная @hash
должна быть инициализирована как:
@hash = [ ['Oracle', @q_oracle], ['Ruby and Rails',@q_ruby] ]
Просмотр должен быть обновлен до:
<% @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 %>
Ответ 2
Это, конечно, возможно, но он ставит очень много логики Ruby в представлении, которое довольно вонючее. Я думаю, что было бы лучше исключить дублирование части тела списка вопросов в частичное.
Главное представление...
<h2>Oracle</h2>
<%= render :partial => 'question_list', :locals => {:questions => @q_oracle} %>
<h2>Ruby and Rails</h2>
<%= render :partial => 'question_list', :locals => {:questions => @q_ruby} %>
Частичный: _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 %>
Этот подход более читабельен, чем вложенный цикл, а также более гибкий с точки зрения настройки структуры страницы. Например: что делать, если вы хотите применить различные стили к каждому списку или поместить разделитель между ними?
Ответ 3
Но, конечно, можно выполнить цикл Hash
.
<% @hash.each do |title, var|
<h2><%= title %></h2>
... so forth ...
<% end %>