加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails-3 – 如何在使用`average()’时在AREL中使用`to_s

发布时间:2020-12-16 20:03:54 所属栏目:百科 来源:网络整理
导读:我正在尝试从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: Revie
我正在尝试从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缓存的东西,所以如果你一个一行地输入上面的控制台,它实际上不会工作,因为漂亮的打印强制的关系.然而,用分号分隔上述并没有新行将会奏效.

或者,您可以直接使用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"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读