带连接的Named_scope

时间:2011-04-05 22:03:18

标签: sql ruby-on-rails

有人可以帮我理解如何将此sql查询转换为named_scope或者方法吗?

背景:旅行可以有很多trip_runs。我试图能够说TripRun.upcoming并根据以下查询返回有效行程中的有效行程

SELECT r.*
FROM trip_run r
LEFT JOIN trips t
ON r.trip_id = t.id
WHERE r.starts_on > NOW()
AND t.is_booked = 1
AND t.is_cancelled IS NULL

谢谢

2 个答案:

答案 0 :(得分:2)

这假设您正在使用Rails 3和AREL。编辑Trip和TripRun的模型文件,如下所示:

class Trip < ActiveRecord::Base
    has_many :trip_runs
    scope :booked, where("is_booked = 1 and isnull(is_cancelled)")

end

class TripRun < ActiveRecord::Base
    belongs_to :trip
    scope :upcoming, where("starts_on > NOW()")

end

然后像这样访问:

Trip.booked.trip_runs.upcoming

有很多方法可以混合和匹配这些模式以获得类似的效果并创建访问数据的方法。

答案 1 :(得分:0)

根据Joshua的回答,但对于rails 2.3:

class Trip < ActiveRecord::Base
  has_many :trip_runs
  named_scope :booked, :conditions => 'is_booked = 1 AND is_cancelled IS NULL'
end

class TripRun < ActiveRecord::Base
  belongs_to :trip
  named_scope :upcoming, :conditions => 'starts_on > NOW()'
end

Trip.booked.trip_runs.upcoming

或者:

class Trip < ActiveRecord::Base
  has_many :trip_runs
end

class TripRun < ActiveRecord::Base
  belongs_to :trip
  named_scope :upcoming,
              :conditions => 'trip.is_booked = 1 AND trip.is_cancelled IS NULL
                              AND trip_runs.starts_on > NOW()', 
              :joins => :trip
end

TripRun.upcoming

那将使用INNER JOIN而不是LEFT JOIN,但是因为你正在寻找将trip.is_booked设置为非空值的行,结果将是相同的,并且查询将不会更慢。