我的订单视图中有以下代码:
<div class="grid heading">
<div class="grid wrap">
<div class=" unit whole">
<h1>Orders</h1>
</div>
</div>
</div>
<div class="grid wrap">
<div class="unit whole">
<p id="notice"><%= flash[:notice] %></p>
<p id="alert"><%= flash[:alert] %></p>
</div>
</div>
<% @vendors.each do |vendor| %>
<h2><%= vendor.name %></h2>
<% @locations.each do |location| %>
<h3><%= location.address %></h3>
<% @orders.each do |order| %>
<div class="grid wrap">
<div class="unit whole">
<table>
<thead>
<tr>
<th>SKU</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<% order.line_items.each do |line_item| %>
<tr>
<td><%= line_item.product_sku %></td>
<td><%= line_item.product_description %></td>
<td></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<% end %>
<% end %>
<% end %>
订单型号:
class Order < ActiveRecord::Base
belongs_to :location
belongs_to :vendor
has_many :line_items
accepts_nested_attributes_for :line_items
end
位置模型:
class Location < ActiveRecord::Base
has_many :orders
end
供应商模型:
class Vendor < ActiveRecord::Base
has_many :orders
end
LineItem模型:
class LineItem < ActiveRecord::Base
belongs_to :order
end
我需要以下示例输出:
Vendor A
Location 1
Order:
1. sku:111, description:zzz
2. sku:222, description:yyy
Location 2
Order:
1. sku:333, description:zzz
2. sku:444, description:yyy
Vendor B
Location 1
Order:
1. sku:aaa, description:zzz
2. sku:bbb, description:yyy
Location 2
Order:
1. sku:ccc, description:zzz
2. sku:ddd, description:yyy
等等。
但是,它会显示所有供应商下所有地点和所有地点的所有订单。
答案 0 :(得分:0)
如果供应商has_many:位置和位置has_many:orders,那么您可以像这样构建循环:
<% @vendors.each do |vendor| %>
<h2><%= vendor.name %></h2>
<% @locations.each do |location| %>
<h3><%= location.address %></h3>
<% vendor.orders.where(location_id: location.id).each do |order| %>
<% end %>
<% end %>
<% end %>
答案 1 :(得分:0)
首先,您应该更改关联以使层次结构更顺畅。至少位置应该属于供应商和订单belongs_to位置,除非存在这种情况,这不适用于您的业务案例,这使事情变得复杂。
您在每个循环中都获得了所有内容,因为您的实例变量不会像您希望它们被表示一样占据父项。修复关联后,可以从正在迭代的对象中调用子东西:
<% @vendors.each do |vendor| %>
<h2><%= vendor.name %></h2>
<% vendor.locations.each do |location| %>
<h3><%= location.address %></h3>
<% location.orders.each do |order| %>
<% order.line_items.each do |line_item| %>
...
<% end %>
<% end %>
<% end %>
<% end %>
然而,有一种更简单,更Railsy的方法:
# index.html.erb
<%= render @vendors %>
# views/vendors/_vendor.html.erb
<h2><%= vendor.name %></h2>
<%= render vendor.locations %>
# views/locations/_location.html.erb
<h3><%= location.address %></h3>
<%= render location.orders %>
# views/order/_order.html.erb
<% order.line_items.each do |line_item| %>
...
<% end %>
当以这种方式使用render
时,Rails将自动迭代关联,默认为每个关联调用部分classname/_classname.html.erb
。在这些部分中,Rails自动为对象分配一个局部变量,其名称与partial相同,这就是为什么在_vendor.html.erb
内你可以使用vendor
变量在当前迭代中调用对象上的方法
您可能希望在查询中使用预先加载来填充@vendor
以避免n + 1问题。好处是你可以摆脱@orders
,@locations
等等。