gpt4 book ai didi

ruby-on-rails-3 - 使用 `to_sql` 时如何在 AREL 中使用 `average()` ?

转载 作者:行者123 更新时间:2023-12-03 20:12:05 25 4
gpt4 key购买 nike

我正在尝试从 AREL 获取 SQL,但在我使用 average(:stars) 的情况下它不起作用:

这有效:

Review.where("reviewed_user_id = ?", self.reviewed_user_id).to_sql
#=> "SELECT `reviews`.* FROM `reviews` WHERE (reviewed_user_id = 3)"

这会导致 NoMethodError :
Review.where("reviewed_user_id = ?", self.reviewed_user_id).average(:stars).to_sql
#=> undefined method `to_sql' for 3:Fixnum

这意味着 to_sql在 AREL 的结果上而不是在 AREL 对象上被调用 - 但为什么呢?

如何获取生成的 SQL?

最佳答案

发生这种情况的原因是平均方法在 ActiveRecord::Relation 上。 ,而不是强制计算的 Arel。

m = Review.where('id = ?', 42).method(:average)
#=> #<Method: ActiveRecord::Relation(ActiveRecord::Calculations)#average>
m.source_location # or m.__file__ if you're on a different version of Ruby
#=> ["/Users/jtran/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.0.4/lib/active_record/relation/calculations.rb", 65]

通过查看 ActiveRecord::Calculations 的内部结构,您可以推导出如何获取它使用的 SQL。
my_reviewed_user_id = 42
relation = Review.where('reviewed_user_id = ?', my_reviewed_user_id)
column = Arel::Attribute.new(Review.unscoped.table, :stars)
relation.select_values = [column.average]
relation.to_sql
#=> "SELECT AVG(\"reviews\".\"stars\") AS avg_id FROM \"reviews\" WHERE (reviewed_user_id = 42)"

如果您在控制台上工作,请小心。 ActiveRecord::Relation缓存东西,所以如果你逐行在控制台中输入上面的内容,它实际上是行不通的,因为 pretty-print 会强制关系。但是,用分号分隔上述内容并且没有新行将起作用。

或者,您可以直接使用 Arel,如下所示:
my_reviewed_user_id = 42
reviews = Arel::Table.new(:reviews)
reviews.where(reviews[:reviewed_user_id].eq(my_reviewed_user_id)).project(reviews[:stars].average).to_sql
#=> "SELECT AVG(\"reviews\".\"stars\") AS avg_id FROM \"reviews\" WHERE \"users\".\"reviewed_user_id\" = 42"

关于ruby-on-rails-3 - 使用 `to_sql` 时如何在 AREL 中使用 `average()` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5173015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com