在Rails中使用命名范围作为子查询

时间:2012-08-09 16:11:43

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2

在我的Rails应用程序中,我想要将一个表与另一个表的命名范围连接起来。有没有办法做到这一点,而不必为我的连接语句重写纯SQL中的命名范围?

基本上,有没有办法做这样的事情?

class Foo < ActiveRecord::Base
  scope :updated_today, where('updated_at > ?', DateTime.now.prev_day)
end

Bar.joins(Foo.updated_today)

Bar.joins生成以下SQL的地方:

SELECT * FROM bars
INNER JOIN
  (SELECT * FROM foos WHERE updated_at > 2012-8-9) AS t0
ON bar_id = bars.id

2 个答案:

答案 0 :(得分:2)

您可以使用merge方法将范围连接到其他模型的查询:

Bar.joins(:foos).merge(Foo.updated_today)

我还没有看到大量关于此的文档(Rails API甚至没有关于方法本身的任何文档),但这里有一个相当不错的blog post给出了相当详细的示例

另外,只是注意到Advanced Queries in Rails 3上的RailsCast中提到了这一点。

答案 1 :(得分:2)

我不相信有任何专门为此做的设计方法。但是,您可以使用ActiveRecord::Relation的{​​{3}}方法将范围的完整SQL查询作为字符串获取,然后可以将其用作连接语句中的子查询,如下所示:

Bar.joins("INNER JOIN (#{Foo.updated_today.to_sql}) as t0 ON bar_id = bars.id")