1

我可能在这里忽略了一种简单的方法,但是编写在 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 方式来做这样的事情?或者任何人都可以推荐我可以学习的任何示例代码。

我的实际模型比我描述的要复杂一些,我想知道是否应该花时间调试代码,或者是否应该采用更简单的方法。这似乎是一个相当普遍的要求。

编辑

我的代码示例

#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>
4

1 回答 1

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 %>
于 2013-02-04T05:46:03.063 回答