检索具有条件的多个关联数据

时间:2016-12-01 13:54:00

标签: ruby-on-rails ruby-on-rails-5

我已经做了几年的程序员(我主要使用PHP / CakePHP),但我是Ruby on Rails的新手。

我有一个关于检索多个条件关联数据的问题。

我有以下四种模式:

class Questionnaire < ApplicationRecord
  has_many :sections
end

class Section < ApplicationRecord
  belongs_to :questionnaire
  has_many :questions
  has_many :non_questions

  def elements
    (questions + non_questions).sort_by(&:order)
  end

end

class Question < ApplicationRecord
  belongs_to :section

  validates_date :starts_on, allow_blank: true
  validates_date :expires_on, allow_blank: true
end

class NonQuestion < ApplicationRecord
    belongs_to :section
end

我目前希望在视图中显示整个调查问卷 - 这是所有部分的问题和非问题,在一个页面和正确的顺序中。我还想从视图中传递一个日期参数,该参数将仅用于检索相应的活动问题,基于starts_on和expires_on日期列。

使用CakePHP,我会通过使用具有条件的Left Joins将所有数据预加载并存储在模型中的变量中。我尝试使用rails(使用所有可能的连接组合,包括,left_outer_joins)和where条件执行类似操作,但是当我(例如,调用questionnaire.sections.first.elements时,它会运行新查询而不应用我的条件。我错过了什么吗?有没有&#34;正确&#34;,红宝石的方式来做这样的事情?或者根据我的应用程序的要求,是否有更好的方法来解决这个问题?

提前致谢

2 个答案:

答案 0 :(得分:1)

对于rails中的eager loader,您使用includes。例如,对于您的模型,您可以执行以下操作:

Questionnaire.includes(sections: [:questions, :non_questions]).references(:question).where("(questions.exp‌​ires_on >= :time OR questions.expires_on IS NULL) AND (questions.starts_on IS NULL OR questionsstarts_on <= :time)" , time: Time.now) 

如果要访问多次检索的那组记录,则应该将其分配给某个变量,这样就不会对db进行新的查询。希望它启发你的问题

答案 1 :(得分:0)

这样的东西
Questionnaire.includes(
  sections: [:questions, :non_questions]
).where("questions.starts_on <= :time AND questions.expires_on > :time", time: Time.now)