Rails 3.2中具有条件的多个和列

时间:2013-04-03 03:11:15

标签: ruby-on-rails activerecord ruby-on-rails-3.2

我在以下型号上努力使用N + 1:

class Transaction < ActiveRecord::Base
  attr_accessible :amount

  belongs_to :user

  scope :retail, where("wholesale = 0")
  scope :wholesale, where("wholesale = 1")
end

class User < ActiveRecord::Base
  attr_accessible :name, :email

  has_many :transactions
end

我需要保留零售/批发的范围(它们可以是方法),因为它们被广泛使用。但是,我很难将它们纳入一份报告,该报告按用户的基础对零售和批发交易进行总结。

我能得到的最接近的是两个查询:

Transaction.retail.group(:user_id).sum(:amount)
Transaction.wholesale.group(:user_id).sum(:amount)

返回两个有序哈希值。该报告需要用户/电子邮件,因此在合并两个哈希值后我将回到N + 1问题。

我尝试过选择:

Transaction
.joins(:user)
.select("users.name, users.email, sum(amount) as wholesale_amount")
.where(wholesale: true)

但它返回[#<Transaction >]这是奇怪的。我无法访问返回数组中的任何属性或使用它。

最好,我想用一个查询来做这件事。以下是直接返回我正在寻找的SQL:

SELECT 
  u.name,
  u.email, 
  SUM(CASE WHEN wholesale = 1 THEN amount ELSE 0 END) AS wholesale_amount, 
  SUM(CASE WHEN wholesale = 0 THEN amount ELSE 0 END) AS retail_amount 
FROM transactions r 
LEFT JOIN users u ON u.id = r.user_id 
GROUP BY user_id 
ORDER BY u.name;

...但它复制了条件条件中的范围逻辑。

我觉得有一个明显的答案我错过了。

编辑: 这就是我现在最终要做的事情。

Transaction
  .joins(:user)
  .select("users.name")
  .select("users.email")
  .select("SUM(CASE WHEN wholesale = 0 THEN amount ELSE 0 END) AS retail_available")
  .select("SUM(CASE WHEN wholesale = 1 THEN amount ELSE 0 END) AS wholesale_available")
  .select("SUM(CASE WHEN wholesale = 1 THEN amount ELSE 0 END) + SUM(CASE WHEN wholesale = 0 THEN amount ELSE 0 END) AS total_available")
  .group("users.id")
  .having("SUM(CASE WHEN wholesale = 1 THEN amount ELSE 0 END) + SUM(CASE WHEN wholesale = 0 THEN amount ELSE 0 END) > 0")
  .order("users.name")

我可能会做的是避免重复,将wholesale = 0字符串放在方法中,并将它们用于范围条件和此方法。我不是这种方法的粉丝,也许是尖叫的东西可以让它更容易,我不知道。它虽然有效。

如果有人对此采用类似红宝石的方法,我会保持开放状态。

0 个答案:

没有答案