Ruby on rails 如何在Rails中设置双向动态表

Ruby on rails 如何在Rails中设置双向动态表,ruby-on-rails,Ruby On Rails,我可能忽略了一个简单的方法,但是编写一个在两个轴上动态的表的最佳方法是什么。我使用的是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_

我可能忽略了一个简单的方法,但是编写一个在两个轴上动态的表的最佳方法是什么。我使用的是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
在Region show视图中,我想显示一个表,其中列出列标题处的商店、行标题处的产品,并计算每个单元格的平均
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>
#视图/区域/show.html.erb
店名
:销售)%>

您可以尝试使用此方法计算每家店铺的平均销售额

Shop.joins(:sales).average(:价格,组::产品id)

这将产生一个散列,其中键是产品ID,值是该产品的平均值。如果您想显示比产品id更多的详细信息,可以将
:group
选项更改为类似(使用postgre)

Shop.joins(sales::product).average(:价格,组:“product|id| |?”-“| products.name”)

更新:在问题上使用视图模板(警告,这在一大组记录上会很慢)

#视图/区域/show.html.erb
店名
更新:这可能是一种更快的方法

# 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 %>
#控制器
@shops=@region.shops
@products=Product.joins(:shops).where(shops:{region\u id:@region.id})
@平均数=销售。加入(:商店)。平均数(:价格,组:['shops.id','shops.name','sales.product\u id])
#看法
店名

您可以尝试使用此方法计算每家店铺的平均销售额

Shop.joins(:sales).average(:价格,组::产品id)

这将产生一个散列,其中键是产品ID,值是该产品的平均值。如果您想显示比产品id更多的详细信息,可以将
:group
选项更改为类似(使用postgre)

Shop.joins(sales::product).average(:价格,组:“product|id| |?”-“| products.name”)

更新:在问题上使用视图模板(警告,这在一大组记录上会很慢)

#视图/区域/show.html.erb
店名
更新:这可能是一种更快的方法

# 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 %>
#控制器
@shops=@region.shops
@products=Product.joins(:shops).where(shops:{region\u id:@region.id})
@平均数=销售。加入(:商店)。平均数(:价格,组:['shops.id','shops.name','sales.product\u id])
#看法
店名

Hi jvnil,谢谢你这句有用的话。不过,我仍在努力了解如何将计算结果构建到表中(我希望我的速度很慢)。我已经用我的代码更新了我的问题。它没有按原样工作,即使是这样,这种方法的性能也不理想。非常感谢有人给我指点,帮助我想象这是如何运作的。嘿@AndyHarvey,我已经更新了我的答案。如果您只需要显示文本,您可以使用我的第一个答案,这样您就不会创建更快的活动记录对象。如果您需要访问商店和产品,请使用第二个。太好了,我知道我的查询太多了!同意你的观点,表现可能会受到影响。有没有更好的方法来实现这一点,从而最小化数据库交互?或者这是它得到的最好的吗?嗨,jvnil,谢谢你这句有用的话。不过,我仍在努力了解如何将计算结果构建到表中(我希望我的速度很慢)。我已经用我的代码更新了我的问题。它没有按原样工作,即使是这样,这种方法的性能也不理想。非常感谢有人给我指点,帮助我想象这是如何运作的。嘿@AndyHarvey,我已经更新了我的答案。如果您只需要显示文本,您可以使用我的第一个答案,这样您就不会创建更快的活动记录对象。如果您需要访问商店和产品,请使用第二个。太好了,我知道我的查询太多了!同意你的观点,表现可能会受到影响。有没有更好的方法来实现这一点,从而最小化数据库交互?或者这是它得到的最好的结果?