Rails 3.如何通过虚拟属性执行“where”查询?

时间:2012-03-13 14:50:04

标签: ruby-on-rails ruby activerecord associations

我有两个模型:ScheduledCourse和ScheduledSession。

scheduled_course has_many scheduled_sessions

scheduled_session belongs_to scheduled_course

ScheduledCourse有一个虚拟属性......

def start_at
  s = ScheduledSession.where("scheduled_course_id = ?", self.id).order("happening_at ASC").limit(1)
  s[0].happening_at
end

... start_at虚拟属性检查属于ScheduledCourse的所有ScheduledSessions,并选择最早的。所以start_at是第一个会话发生的日期。

现在我需要在控制器中写入,以便只获取今天开始并进入未来的记录。此外,我需要编写另一个只获得过去课程的查询。

我无法执行以下操作,因为start_at是虚拟属性

@scheduled_courses = ScheduledCourse.where('start_at >= ?', Date.today).page(params[:page])

@scheduled_courses = ScheduledCourse.where('start_at <= ?', Date.today)

SQLite3::SQLException: no such column: start_at: SELECT  "scheduled_courses".* FROM "scheduled_courses"  WHERE (start_at >= '2012-03-13') LIMIT 25 OFFSET 0

3 个答案:

答案 0 :(得分:3)

您无法对不在数据库中的列执行SQL查询。如果您打算对它进行查询而不是伪列,您应该考虑将其设为真正的数据库列;但是如果你想从这个系列中选择项目,你仍然可以这样做。你只需要在Ruby中完成它。

ScheduledCourse.page(params).find_all {|s| s.start_at >= Date.today}

答案 1 :(得分:3)

Veraticus是对的;您不能在查询中使用虚拟属性。

但是,我认为你可以做到:

ScheduledCourse.joins(:scheduled_sessions).where('scheduled_courses.happening_at >= ?', Date.today)

它会通过匹配id将表连接在一起,然后你可以查看'happeing_at'列,这就是你的'start_at'属性。

免责声明:未经测试,但应该有效。

答案 2 :(得分:1)

我想知道这是否可以通过子查询来解决(子查询首先要找到最早的日期)。如果是这样,也许解决方案here可能有助于指出一个有用的方向......