2012-08-09 32 views
2

在我的Rails应用程序中,我想要连接一个表与另一个表的命名作用域。有没有办法做到这一点,而不必为我的联合声明重写纯SQL中的命名范围?在Rails中使用命名作用域作为子查询

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

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 

回答

1

我不相信有任何专门为此设计的方法。你可以,但是,使用的ActiveRecord::Relationto_sql方法来获取范围完整的SQL查询语句的字符串,它可以作为一个子查询的连接语句,然后使用,就像这样:

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

是的,我只是回答我自己的问题。如果有人有这样做的更好的方式,但请随时chime英寸 – Ajedi32 2012-08-09 17:50:26

+1

完全可以接受回答你自己的问题,特别是当我们其他人似乎无法这样做... :) – BaronVonBraun 2012-08-09 17:53:11

2

可以使用merge方法来连接到示波器另一种模式的查询:

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

我还没见过(Rails API甚至没有关于该方法本身的任何文档),但这里有一个相当不错的blog post给出了一个相当详细的例子。

此外,只是注意到这是在一个RailsCast上提到Advanced Queries in Rails 3

+1

这真的很有趣,但它不是我想要的。我不想将范围加入到查询中,我想使用作用域生成的查询作为子查询,我可以调用LEFT OUTER JOIN。 (我会更新问题以使其更清楚。) – Ajedi32 2012-08-09 16:55:21