[英]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及其对应的类型)。
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:
当我想打印所有类型时,此代码为我提供了所需的输出:
<% @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.