按最近回答的问题排序并过滤特定用户未回答的问题
Ordering questions by most recently answered and filtering those unanswered by a particular user
我在编写 returns 我想要的结果的 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 }
但是这个 returns Array
个 Question
个对象而不是我更喜欢的 ActiveRecord::Relation
个对象。
有人可以帮助我理解为什么我不能按照所写的那样链接 recently_answered
和 unanswered_by
以及我如何重写它以获得我想要的结果?谢谢。
您应该在 unanswered_by
方法的 SQL 查询中添加 table 的名称:
def self.unanswered_by(user)
where('questions.id NOT IN (SELECT question_id FROM answers WHERE user_id = ?)', user.id)
#^^^^^^^^^ table's name added here
end
因为如果您将此与 joins
/includes
结合使用,您的数据库适配器将不知道您 table 来自哪个 ID(错误消息如column id is ambiguous
).
此外,对于这两种方法,您可能应该使用 scope
。
我在编写 returns 我想要的结果的 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 }
但是这个 returns Array
个 Question
个对象而不是我更喜欢的 ActiveRecord::Relation
个对象。
有人可以帮助我理解为什么我不能按照所写的那样链接 recently_answered
和 unanswered_by
以及我如何重写它以获得我想要的结果?谢谢。
您应该在 unanswered_by
方法的 SQL 查询中添加 table 的名称:
def self.unanswered_by(user)
where('questions.id NOT IN (SELECT question_id FROM answers WHERE user_id = ?)', user.id)
#^^^^^^^^^ table's name added here
end
因为如果您将此与 joins
/includes
结合使用,您的数据库适配器将不知道您 table 来自哪个 ID(错误消息如column id is ambiguous
).
此外,对于这两种方法,您可能应该使用 scope
。