【发布时间】:2015-09-29 20:46:47
【问题描述】:
我在编写返回所需结果的 Active Record 查询时遇到问题。我有以下设置:
删节User型号:
class User < ActiveRecord::Base
has_many :answers
end
删节Answer型号:
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
删减的Question 型号:
class Question < ActiveRecord::Base
has_many :answers
def self.unanswered_by(user)
where(
'id NOT IN (SELECT question_id FROM answers WHERE user_id = ?)',
user.id
)
end
def self.recently_answered
includes(:answers).order('answers.updated_at DESC')
end
end
我正在尝试返回ActiveRecord::Relation,它按最近回答的问题排序问题,然后过滤结果,使其仅包含current_user 尚未回答的问题。
理想情况下,我想写
Question.recently_answered.unanswered_by current_user
但这似乎不起作用,由于我对 SQL 的了解有限,我很难理解为什么。
这是我在 Rails 控制台中运行时得到的结果:
me = User.find(8)
Question.recently_answered.unanswered_by me
=> SQL (0.5ms) SELECT `questions`.`id` AS t0_r0,
`questions`.`question_text` AS t0_r1,
`questions`.`example_answer` AS t0_r2,
`questions`.`created_at` AS t0_r3,
`questions`.`updated_at` AS t0_r4,
`answers`.`id` AS t1_r0,
`answers`.`question_id` AS t1_r1,
`answers`.`user_id` AS t1_r2,
`answers`.`answer_text` AS t1_r3,
`answers`.`created_at` AS t1_r4,
`answers`.`updated_at` AS t1_r5
FROM `questions` LEFT OUTER JOIN `answers`
ON `answers`.`question_id` = `questions`.`id`
WHERE (id NOT IN (SELECT question_id FROM answers WHERE user_id = 8))
ORDER BY answers.updated_at DESC
#<ActiveRecord::Relation:0x3fd42e362a80>
运行Question.recently_answered.unanswered_by(me).to_sql 给了我这个:
=> "SELECT `questions`.*
FROM `questions`
WHERE (id NOT IN (SELECT question_id
FROM answers WHERE user_id = 8))
ORDER BY answers.updated_at DESC"
我现在正在解决这个问题
Question
.recently_answered
.reject { |q| q.answers.map(&:user_id).include? current_user.id }
但这会返回Question 对象中的Array,而不是我更喜欢的ActiveRecord::Relation。
有人能帮我理解为什么我不能像写的那样链接recently_answered 和unanswered_by,以及如何重写它以便得到我想要的结果?谢谢。
【问题讨论】:
-
在
unanswered_by方法的实现中,id列可能不明确(如果您进行连接)。在id之前使用表名,以确保没有对id列的模糊调用(使用questions.id NOT IN ...) -
另外,这些方法应该定义为
scope(在你的情况下:scope :recently_answered, -> { includes(:answers).order('interview_answers.updated_at DESC') }) -
@MrYoshiji 谢谢。现在您指出
id在unanswered_by方法中是模棱两可的,这很有意义。当我按照您的建议执行questions.id NOT IN ...时,它似乎有效。很好地呼吁在这里使用范围而不是类方法。我会重写它们。添加作为我很乐意接受的答案。再次感谢您帮助我理解。
标签: mysql ruby-on-rails activerecord ruby-on-rails-3.2