【问题标题】:rails named scope issuesrails 命名范围问题
【发布时间】:2009-10-16 13:59:40
【问题描述】:

我有两个命名范围...它们都单独工作,但组合时不起作用。

  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)

命名范围的货币有效,但总数无效...

有什么想法吗?

【问题讨论】:

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


    【解决方案1】:

    我认为你有几个问题。

    • 两个作用域都定义了“as price”并且它们冲突,这将产生无效的 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 }}
    

    【讨论】:

    • 我采用了更长和最后的方法......它工作正常。谢谢
    【解决方案2】:

    遗憾的是,named_scope 目前除了条件之外没有成功链接任何其他内容。

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2012-07-05
        • 1970-01-01
        • 2013-08-06
        • 2020-01-17
        • 2012-10-07
        • 1970-01-01
        • 1970-01-01
        • 2019-01-25
        相关资源
        最近更新 更多