简体   繁体   English

Rails ERB遍历数组

[英]Rails ERB iterate over array

I'm trying to experiment with blocks and how to iterate over collections in ERB. 我正在尝试使用块以及如何遍历ERB中的集合。 I have a models in a one-to-many relatinship (Channel and their corresponding types). 我有一对多关系的模型(Channel及其对应的类型)。

controller 调节器

class HomePageController < ActionController
   def index
    @channels =  Channel.all
   end
end

Then in the view, I iterate over all the attributes belonging to a Channel. 然后在视图中,遍历属于Channel的所有属性。 When I want to print all types, this code gives me the desired output: 当我想打印所有类型时,此代码为我提供了所需的输出:

view 视图

<% @channels.each do |channel| %>
    <% @types.each do |type| %>
        <%= Type.find(type).name %>
    <% end %>
<% end %>

At first I tried to achieve this by using the yield keyword in a neat one-liner but I couldn't manage to print anything to the browser, only to the console 最初,我尝试通过在整洁的单行代码中使用yield关键字来实现此目的,但是我无法设法将任何内容打印到浏览器,仅打印到控制台

<% @types.each {|type| yield Type.find(type).name } %>

Is there an equivalent one-liner? 是否有等效的单线?

First of all this method is so inefficient, you are doing n-queries, to find each record of type Type instead convert those into an array of types by using a single query in the controller, assume that that array is in type_ids 首先,这种方法效率低下,您正在执行n查询,以查找Type每个记录,而不是通过使用控制器中的单个查询将它们转换为类型数组,并假设该数组位于type_ids

# controller
@channels = Channel.includes(:types) # avoiding n+1 queries

# view
<% @channels.each do |channel| %>
  # some channel info output
  <% channel.types.each do |type| %>
    <%= type.name %>
  <% end %> # types loop
<% end %> # channel loop

As @Almaron mentioned, you could render a partial for more simplification, if you have a partial called _type.html.erb you can call render directly 如@Almaron所述,您可以渲染部分以便于简化,如果您有一个名为_type.html.erb的部分,则可以直接调用render

# view
<%= render channel.types %>

Rails will do all the iterating and rendering. Rails将进行所有的迭代和渲染。

First of all, this kind of code does not belong to the view. 首先,这种代码不属于视图。 Don't tackle the database from the view (in your case Type.find() ). 不要从视图中处理数据库(在您的情况下为Type.find() )。 Move it to the controller where it belongs. 将其移动到它所属的控制器。

The second thing to note is the difference between <%= and <% tags. 要注意的第二件事是<%=<%标签之间的区别。 The first one outputs the returned result, while the second one doesn't. 第一个输出返回的结果,而第二个则不。 The problem with .each is that it returns the object it has been used on, so in your case if you just go <%= @types.each {|type| Type.find(type).name } %> .each的问题在于它返回已使用过的对象,因此在您的情况下,如果您只是<%= @types.each {|type| Type.find(type).name } %> <%= @types.each {|type| Type.find(type).name } %> you'll get the @types array printed out. <%= @types.each {|type| Type.find(type).name } %>您将输出@types数组。

If you want to simplify that code, you can use a helper method for iterating and a partial for rendering each item. 如果要简化该代码,则可以使用助手方法进行迭代,而可以使用一部分方法来呈现每个项目。 That way you get something like this <% collection_iterate @items, 'item_partial' %> 这样,您将得到如下内容: <% collection_iterate @items, 'item_partial' %>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM