我可能在这里忽略了一个简单的方法,但是在2轴上编码动态表的最佳方法是什么。我正在使用Rails 3.2
例如,假设我有以下模型
class Region
has_many :shops
end
class Shop
has_many :sales
has_many :products, through: :sales
end
class Sale
belongs_to :shop
belongs_to :product
end
class Product
has_many :sales
has_many :shops, through: :sales
end
在区域展示视图中,我想显示一个表格,列出商店列标题,商品列为行标题,并计算每个单元格的平均值Sale.price
。
我陷入混乱的嵌套块,计算出的值似乎与我的预期不符。
是否有一种简单的Rails-y方式可以做这样的事情?或者任何人都可以推荐我可以学习的任何示例代码
我的实际模型比我描述的要复杂得多,我想知道是否应该花时间处理我的代码进行调试,或者我是否应该遵循更简单的方法。这似乎是一个相当普遍的要求。
修改
我的代码示例
#views/regions/show.html.erb
<table>
<tr>
<th>Shop Name</th>
<% for product in @region.products.uniq %>
<th><%= product.name%></th>
<% end %>
</tr>
<% for shop in @region.shops.uniq %>
<tr>
<td><%= shop.name %></td>
<% for product in @region.products.uniq %>
<td><%= product.sales.average(:price, conditions: ['sale.shop_id = ?', shop], :include => :sale) %></td>
<% end %>
</tr>
<% end %>
</table>
答案 0 :(得分:1)
您可以尝试这样计算每家商店的平均销售额。
Shop.joins(:sales).average(:price, group: :product_id)
这将产生一个散列,其中键是产品ID,值是该产品的平均值。如果您想显示更多详细信息而不仅仅是产品ID,可以将:group
选项更改为(使用postgre)
Shop.joins(sales: :product).average(:price, group: "product_id || ' - ' || products.name")
更新:在问题上使用视图模板(警告,这对一大组记录来说会很慢)
#views/regions/show.html.erb
<table>
<tr>
<th>Shop Name</th>
<% @region.products.each do |product| %>
<th><%= product.name%></th>
<% end %>
</tr>
<% @region.shops.each do |shop| %>
<tr>
<td><%= shop.name %></td>
<% shop.products.each do |product| %>
<td><%= product.sales.where(shop_id: shop.id).average(:price) %></td>
<% end %>
</tr>
<% end %>
</table>
更新:这可能是一种更快捷的方式
# controller
@shops = @region.shops
@products = Product.joins(:shops).where(shops: { region_id: @region.id })
@averages = Sale.joins(:shop).average(:price, group: ['shops.id', 'shops.name', 'sales.product_id])
# view
<tr>
<th>Shop Name</th>
<% @products.each do |product| %>
<th><%= product.name%></th>
<% end %>
</tr>
<% @shops.each do |shop| %>
<tr>
<td><%= shop.name %></td>
<% @products.each do |product| %>
<td><%= @averages[[shop.id, shop.name, product.id]] || 0 %></td>
<% end %>
</tr>
<% end %>