我正在Rails 5中运行以下查询,目的是寻找具有最高音调的用户:
User
.select("users.*, COUNT(user_id) as pitch_count")
.unscoped
.joins("LEFT JOIN pitches AS pitches ON pitches.user_id = users.id")
.group("pitch.user_id")
.order("pitch_count DESC")
.limit(5)
但是我得到了错误:
Caused by PG::UndefinedColumn: ERROR: column "pitch_count" does not exist
为什么查询不能按pitch_count排序?
答案 0 :(得分:5)
问题在unscoped方法中。它删除所有先前定义的范围,包括select
语句。请参见以下示例:
User.select(:full_name, :email).unscoped.to_sql
# => SELECT "users".* FROM "users"
User.unscoped.select(:full_name, :email).to_sql
# => SELECT "users"."full_name", "users"."email" FROM "users"
看到区别了吗?在unscoped
定义之后调用的select
完全删除了select
中定义的所有内容。
对于您来说,这意味着您应该修改代码以在模型名称后立即调用unscoped
:
User
.unscoped
.select("users.*, COUNT(user_id) as pitch_count")
.joins("LEFT JOIN pitches AS pitches ON pitches.user_id = users.id")
.group("pitch.user_id")
.order("pitch_count DESC")
.limit(5)
注意:添加新行主要是为了提高可读性,但它在ruby文件中应像这样工作。如果要在rails控制台中执行它。您将必须删除新行
顺便说一句。您仍然可能会收到错误消息,即“ user.id”列必须出现在GROUP BY子句中或在聚合函数中使用。应该通过修改group
语句以使用users.id
而不是pitch.user_id
来解决该问题:
.group("users.id")
答案 1 :(得分:2)
我建议您使用counter_cache使其易于维护并提高性能。通过添加计数器缓存,您可以获得User.reorder(pitches_count: :desc).first
最多音调的用户记录。