按列分组,然后获取Rails中另一列的总和

时间:2015-06-08 04:57:01

标签: ruby-on-rails ruby postgresql

我是初学者,使用Rails 4.2.1和Postgresql一起创建像Yahoo Finance这样的个人股票投资组合。转到“portfolio /:id”应该在下面显示每个投资组合的show.html.erb文件。每个投资组合都与持股表相关联,该持股表包含投资组合中股票的数据以及投资组合中每种股票的份额。 如果用户在同一个投资组合中有两个相同的股票,则应用必须从这两个行中获得“金额”列的总和,并且除了总和之外,还要使用相同的数据创建一行。金额。

模型

User
has_many :portfolios
has_many :holdings

Portfolio
belongs_to :user
has_many :holdings

Holding
belongs_to :user
belongs_to :stock
belongs_to :portfolio

Stock
has_many :holdings

数据库架构

table "holdings"
t.integer  "user_id"
t.integer  "stock_id"
t.integer  "portfolio_id"
t.integer  "amount"
end

table "portfolios"
t.integer  "user_id"
t.string   "name"
end

table "stocks"
t.string   "symbol"
end

PortfoliosController

def show
@holdings = @portfolio.holdings # can't figure out what to do next.
end

# As it is, this just shows rows for every new holding transaction.

show.html.erb

 <% @holdings.each do |holdings| %>
 <tr>
    <td><%= holdings.portfolio.user.name %></td>
    <td><%= holdings.portfolio.name %></td>
    <td><%= holdings.stock.symbol %></td>
    <td><%= holdings.amount %></td>
  </tr>
 <% end %>

错误

@holdings = @portfolio.holdings.sum(:amount, :group => "stock_id" :order=> "sum(amount) DESC")

导致此错误:

NoMethodError at /portfolios/22
undefined method `each' for 171:Fixnum

# And by the way, 171 is the correct sum but it needs to work with the looped table

这:

@holdings = @portfolio.holdings.group(:portfolio_id).sum(:amount)

导致此错误:

NoMethodError at /portfolios/22
undefined method `portfolio' for [22, 171]:Array

我似乎无法让它与每个循环一起使用。

1 个答案:

答案 0 :(得分:0)

花了无数个小时后,我找到了解决方案。这非常难以找到。我实际上在这个页面上找到了答案:group by + sum on multiple columns in rails 3

所以我改变的是:

在控制器中:

@holdings = @portfolio.holdings.select(:stock_id, :portfolio_id, 
"SUM(amount) as sum_amount").group(:stock_id,
:portfolio_id).order("sum_amount DESC")

在视图中:

<tr>
  <td><%= holdings.portfolio.user.name %></td>
  <td><%= holdings.portfolio.name %></td>
  <td><%= holdings.stock.symbol %></td>
  <td><%= holdings.sum_amount %></td>
  </tr>
<% end %>