rails命名范围问题

时间:2009-10-16 13:59:40

标签: sql ruby-on-rails ruby named-scope

我有两个命名的范围......两者都是分开工作,但是当它们组合起来时不起作用。

  named_scope :total, :select => "COUNT(*) as days, AVG(price) as price, SUM(price) AS total", :group => :parent_id
  named_scope :currency, lambda { |code| { :select => "*, price * #{(CurrencyRate.get_rate("USD", (code ||= "USD") ,1))} AS price" } }

示例:

c=Booking.total.currency("EUR").find_all_by_parent_id(63)

总命名范围有效但不是货币...

c=Booking.currency("EUR").total.find_all_by_parent_id(63)

名为范围的货币有效,但不是总数......

有什么想法吗?

3 个答案:

答案 0 :(得分:4)

我认为你有几个问题。

  • 两个范围都定义为“价格”并且它们发生冲突,这将产生无效的SQL

  • 一个范围有一个group子句,但另一个范围没有select子句中非分组属性的聚合函数。这将导致无效的SQL。

请考虑在预订模型上使用计算属性,而不是使sql复杂化的范围。

class Booking
    def currency(code="USD")
        price * CurrencyRate.get_rate(code) ,1)
    end
end

现在你可以:

c=Booking.total.find_all_by_parent_id(63)
for booking in c
    puts booking.currency("EUR")
end

如果您必须使用范围,请考虑将它们组合使用。我意识到你可能不想为每个排列创建命名范围,但我认为必须改变一些东西。您可以创建named_scope:currency_total

named_scope :currency_total, lambda { |code| {:select => "COUNT(*) as days, 
           AVG(price * #{(CurrencyRate.get_rate("USD", (code ||= "USD") ,1))}) as price, 
           SUM(price * #{(CurrencyRate.get_rate("USD", (code ||= "USD") ,1))}) AS total", 
           :group => :parent_id }}

答案 1 :(得分:3)

可悲的是,named_scope目前没有成功排除任何条件。

:select将由仅设置一个命名范围。因此,您应该采用 jrhicks 方法。

顺便说一下:这就是为什么你应该开始每一个:select => "model_name.*, ...,以便Rails获取模型的字段。否则你会遇到其他问题/错误。

答案 2 :(得分:1)

请确保(通过日志)组合调用的结果查询是两个查询的总和,如果是,则2个查询的组合是空集,您需要重新考虑它们一起工作。如果不是,请粘贴您的模型......