【问题标题】:Using Named Scopes as Subqueries in Rails在 Rails 中使用命名范围作为子查询
【发布时间】:2012-08-09 16:11:43
【问题描述】:

在我的 Rails 应用程序中,我想将一个表与另一个表的命名范围连接起来。有没有一种方法可以做到这一点,而不必为我的 join 语句重写纯 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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 是的,我只是回答了我自己的问题。如果有人有更好的方法,请随时加入。
    • 完全可以回答您自己的问题,尤其是当我们其他人似乎无法这样做时...... :)
    【解决方案2】:

    您可以使用merge 方法将作用域连接到另一个模型的查询:

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

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

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

    【讨论】:

    • 这真的很有趣,但这并不是我想要的。我不希望将范围加入查询,我想将范围生成的查询用作子查询,我可以在其上调用 LEFT OUTER JOIN。 (我会更新问题以使这一点更清楚。)
    猜你喜欢
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2021-07-02
    相关资源
    最近更新 更多