使用has_many从一组模型中收集唯一记录

时间:2014-06-30 16:53:06

标签: ruby-on-rails ruby ruby-on-rails-4

我有一个AnswerSheet has_many :answers,每个Answer belongs_to :question

我执行类似@answer_sheet.answers.where(is_correct: false).map(&:question)的操作来获取所有未正确回答的问题。

Question has_many :question_skillshas_many :skills, through: :question_skills,我希望获得针对这组问题的所有独特技能。

我在上面的结果上尝试了.map(&:skills),但这给了我一个ActiveRecord::Associations::CollectionProxy的数组,我认为这不是我想要的。

这似乎也是一场表演噩梦。

如果您对如何改进此问题标题有任何建议,我会非常乐意概括这个问题。

2 个答案:

答案 0 :(得分:1)

您可以使用关联来回答所有这些问题(双关语)。首先,为正确/错误答案添加一些新关联。

class Answer < ActiveRecord::Base
  belongs_to :question
end

class AnswerSheet < ActiveRecord::Base
  has_many :answers

  has_many :incorrect_answers, -> { where is_correct: false }, class_name: 'Answer'
  has_many :incorrectly_answered_questions, class_name: 'Question', through: :incorrect_answers, source: :question

  has_many :correct_answers, -> { where is_correct: true }, class_name: 'Answer'
  has_many :correctly_answered_questions, class_name: 'Question', through: :correct_answers, source: :question

  has_many :skills_for_correct_answers, class_name: 'Skill', through: :correctly_answered_questions, source: :skills
  has_many :skills_for_incorrect_answers, class_name: 'Skill', through: :incorrectly_answered_questions, source: :skills
end

现在您可以更直接地获取记录:

# get all incorrect answers
answer_sheet.incorrect_answers

# get all incorrectly answered questions
answer_sheet.incorrectly_answered_questions

# get all correctly answered questions
answer_sheet.correctly_answered_questions

关于如何找到独特技能的第二个问题可以通过在结果上调用uniq来完成

answer_sheet.skills_for_incorrect_answers.uniq

答案 1 :(得分:0)

通常最好让数据库从单个查询中制定答案。对于第一个查询,这将是:

Question.joins(:answer_sheets, :answers).where(
  'answer_sheets.id = ? and not answers.is_correct', @answer_sheet.id)

以此为模式,第二种:

Skill.joins(:questions, :answer_sheets, :answers).select('skills.id,skills.text').
  where('answer_sheets.id = ? and not answers.is_correct', @answer_sheet.id).
  distinct

我们需要select允许distinct工作。根据需要调整字段。

当然这是未经测试的,但它应该是接近的。