在模板中循环

dem*_*mas 13 ruby-on-rails

我的模板看起来像:

  <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 %>
Run Code Online (Sandbox Code Playgroud)

因此,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 %>
}
Run Code Online (Sandbox Code Playgroud)

可能吗?

Via*_*kov 27

是的,你可以做到.

Ruby 1.9解决方案

在Ruby 1.8中,当标题顺序无关紧要时,可以使用此解决方案.在Ruby 1.9中,标题将按照它们插入哈希的顺序出现.

只需将此变量放在控制器操作中:

@hash = { 'Oracle' => @q_oracle, 'Ruby and Rails' => @q_ruby }
Run Code Online (Sandbox Code Playgroud)

并从您的视图中访问此变量:

<% @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 %>
Run Code Online (Sandbox Code Playgroud)

带有排序键的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 %>
Run Code Online (Sandbox Code Playgroud)

带有数组的Ruby 1.8

在任何ruby版本中,此方法的行为类似于Ruby 1.9 - 标题将按照添加顺序显示.

变量@hash必须初始化为:

@hash = [ ['Oracle', @q_oracle], ['Ruby and Rails',@q_ruby] ]
Run Code Online (Sandbox Code Playgroud)

视图必须更新为:

<% @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 %>
Run Code Online (Sandbox Code Playgroud)


Ste*_*sen 5

这肯定是可能的,但它在视图中放置了大量的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} %>
Run Code Online (Sandbox Code Playgroud)

部分:_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 %>
Run Code Online (Sandbox Code Playgroud)

这种方法比嵌套循环更具可读性,并且在自定义页面结构方面也更灵活.例如:如果要对每个列表应用不同的样式,或者在两者之间放置分隔符,该怎么办?