在我的Rails应用程序中,我允许用户"投票"关于事件。有些活动只是一个特定日期,有些活动正在进行中。
我正在尝试构建一个查询,该查询呈现A)用户未在上投票的所有事件或 B)用户投票的正在进行的事件 over 1个月前。
活动有"正在进行"布尔列。活动有很多票。而且用户有很多票。
这是我的查询,以获取用户未投票的所有事件。它有效。
scope :unvoted, ->(user_id) {
joins(
"LEFT OUTER JOIN votes ON votes.event_id = events.id AND " +
"votes.user_id = #{user_id}"
).where("votes.id IS NULL")
}
我正在尝试添加查询的或部分。我需要包括"正在进行的"用户在一个月前投票的事件。这就是我的尝试:
scope :unvoted, ->(user_id) {
joins(
"LEFT OUTER JOIN votes ON votes.event_id = events.id AND " +
"votes.user_id = #{user_id}"
)
.where(
"votes.id IS NULL OR events.ongoing = ? AND MAX(votes.created_at) < ?", true, 1.month.ago
)
}
但是这给了我错误:
PG :: GroupingError:错误:WHERE
中不允许使用聚合函数
所以我尝试了这个:
scope :unvoted, ->(user_id) {
joins(
"LEFT OUTER JOIN votes ON votes.event_id = events.id AND " +
"votes.user_id = #{user_id}"
).
having('votes.id IS NULL OR events.ongoing = ? AND MAX("votes"."created_at") < ?', true, 1.month.ago).
group("events.id")
}
但是这给了我错误:
错误:列必须出现在GROUP BY子句中或用于聚合函数
我正在寻找的正确查询是什么?
答案 0 :(得分:0)
修改强> 似乎没有办法用HAVING写OR。您可以使用子查询(Using 'OR' between HAVING and WHERE clause in MySQL?)或UNION来解决此问题。
或者为了简单起见,您可以将其分解为两个查询。
仅限ActiveRecord解决方案:https://stackoverflow.com/a/15413611/5213979
答案 1 :(得分:0)
你能试试吗
scope :unvoted, ->(user_id) {
joins(
"LEFT OUTER JOIN votes ON votes.event_id = events.id AND " +
"votes.user_id = #{user_id}"
).where(
"votes.id IS NULL OR events.ongoing = ?", true
).select('events.*, MAX(votes.created_at) as created_at')
).group('events.id')
}
然后在你的方法中,你可以做到
Event.unvoted.select{|e| e.created_at < 1.month.ago}