为类似AR查询实现查询对象的正确方法
问题描述:
我在rails应用程序模型中有两种方法。为类似AR查询实现查询对象的正确方法
def questions_mastered_for(user_id, question_group_ids)
res = UserAnswer
.joins('INNER JOIN question_group_questions ON user_answers.question_id = question_group_questions.question_id')
.joins('INNER JOIN marks ON user_answers.id = marks.user_answer_id')
.group('question_group_questions.question_group_id')
.where(question_group_questions: { question_group_id: question_group_ids })
.where(user_answers: { user_id: user_id })
.where("(marks.boolean_mark_correct = true AND marks.mark_type = 'boolean') OR (marks.fraction_numerator = marks.fraction_denominator AND marks.mark_type = 'fraction')")
.pluck('question_group_questions.question_group_id', 'COUNT(DISTINCT(user_answers.question_id))')
question_group_mastery = {}
question_group_ids.each { |question_group_id| question_group_mastery[question_group_id] = 0 }
res.each { |data| question_group_mastery[data.first] = data.second }
question_group_mastery
end
def questions_attempted_for(user_id, question_group_ids)
res = UserAnswer
.joins('INNER JOIN question_group_questions ON user_answers.question_id = question_group_questions.question_id')
.group('question_group_questions.question_group_id')
.where(question_group_questions: { question_group_id: question_group_ids })
.where(user_answers: { user_id: user_id })
.pluck('question_group_questions.question_group_id', 'COUNT(DISTINCT(user_answers.question_id))')
question_group_attempted = {}
question_group_ids.each { |question_group_id| question_group_attempted[question_group_id] = 0 }
res.each { |data| question_group_attempted[data.first] = data.second }
question_group_attempted
end
如果我们可以从上面的方法看,两者几乎做了类似的查询,唯一的区别是在questions_mastered_for
有额外的加入,where条件marks
表。
我看了一些文章,通常这个特殊的用例可以使用查询对象来解决,但我想知道如何正确实现它?
任何建议,我很感激。
答
def questions_attempted_for_query(user_id, question_group_ids)
UserAnswer
.joins('INNER JOIN question_group_questions ON user_answers.question_id = question_group_questions.question_id')
.group('question_group_questions.question_group_id')
.where(question_group_questions: { question_group_id: question_group_ids })
.where(user_answers: { user_id: user_id })
end
def questions_mastered_for(user_id, question_group_ids)
res = questions_attempted_for_query(user_id, question_group_ids)
.joins('INNER JOIN marks ON user_answers.id = marks.user_answer_id')
.where("(marks.boolean_mark_correct = true AND marks.mark_type = 'boolean') OR (marks.fraction_numerator = marks.fraction_denominator AND marks.mark_type = 'fraction')")
.pluck('question_group_questions.question_group_id', 'COUNT(DISTINCT(user_answers.question_id))')
question_group_mastery = {}
question_group_ids.each { |question_group_id| question_group_mastery[question_group_id] = 0 }
res.each { |data| question_group_mastery[data.first] = data.second }
question_group_mastery
end
def questions_attempted_for(user_id, question_group_ids)
res = questions_attempted_for_query(user_id, question_group_ids)
.pluck('question_group_questions.question_group_id', 'COUNT(DISTINCT(user_answers.question_id))')
question_group_attempted = {}
question_group_ids.each { |question_group_id| question_group_attempted[question_group_id] = 0 }
res.each { |data| question_group_attempted[data.first] = data.second }
question_group_attempted
end