Rails 4使用嵌套属性多次过滤模型

时间:2016-03-03 21:54:00

标签: sql ruby-on-rails activerecord

我有三个主要模型来处理这个案例。简而言之,他们的关系是这样的:

class Person < ActiveRecord::Base
  has_many :sessions, dependent: :delete_all, inverse_of: :person
  has_many :answers, through: :sessions
end
class Session < ActiveRecord::Base
  belongs_to :person, inverse_of: :sessions
  has_many :answers
end
class Answer < ActiveRecord::Base
  belongs_to :session
end

为了简短并专注于问题,我将总结模型属性,并只关注答案模型属性,因为它们是我需要做的唯一需要的事情。 Answers模型具有以下属性:

# == Schema Information
#
# Table name: answers 
#
#  id                 :integer          not null, primary key
#  session_id         :integer
#  question_option_id :integer
#  created_at         :datetime         not null
#  updated_at         :datetime         not null
#

我想要的是根据表单提供的question_option_id值过滤人员记录,用户可以选择过滤一个或多个答案问题选项值。 这些值没有问题,但是我试过没有成功过滤人员记录,这是我最接近的部分成功:

people = Person.all
people = people.joins(:answers).uniq.where(answers: {question_option_id: some_param})

有了这个,我已经能够使用一个问题选项的值进行过滤,当我尝试过滤多个问题选项而没有返回任何内容时出现问题,这就是我尝试过的:

people = Person.all
people = people.joins(:answers).uniq.where(answers: {question_option_id: some_question_option_id_param})
people = people.joins(:answers).uniq.where(answers: {question_option_id: another_question_option_id_param})

问题在于,在这些情况下,查询会搜索具有一个答案且具有不可能的question_option_id值的人。我试图完成的是进行查询以搜索在他们拥有的所有答案中具有这些问题选项id的人。很抱歉,如果我很难理解,但这就是我想要做的事情,我不确定我是否采取了正确的方法,欢迎提出任何建议。

1 个答案:

答案 0 :(得分:1)

这是relational division的情况。对于你的情况,这样的事情可以做到这一点:

# question_option_ids = [some_param, some_other_param, ...]
people = Person.all
question_option_ids.each do |question_option_id|
  people = people.where('EXISTS (SELECT * FROM sessions s INNER JOIN answers a ON s.id = a.session_id WHERE s.person_id = people.id AND a.question_option_id = ?)', question_option_id)
end