是否可以为关联获取ActiveRecord :: Relation对象

时间:2010-11-14 08:21:34

标签: activerecord ruby-on-rails-3 associations arel

  1. 关联方法(例如has_manybelongs_to定义的关联方法是否会使用ActiveRecord::Relation

  2. 如果是这样,是否可以获取正在使用的ActiveRecord::Relation对象。

  3. 我们都知道,在使用Query Interface创建查询时,Rails 3在后台大量使用ActiveRecord::Relation个对象和Arel::Relation个对象。每当我们使用查询接口的selectjoins等方法时,都会返回ActiveRecord::Relation个对象。但是,在调用模型的关联方法时似乎不是这种情况。而是立即执行查询,并返回关联模型的实例或实例数组。

    考虑以下模型:

    post.rb

    class Post < ActiveRecord::Base
      belongs_to :user
    end
    

    user.rb

    class user < ActiveRecord::Base
      has_many :posts
    end
    

    示例:

    u = User.first
    u.posts
    

    调用u.posts会返回一系列帖子,而不是ActiveRecord::Relation的实例。我想知道是否有可能获得正在使用的ActiveRecord::Relation ,如果它正在被使用,可能是使用Arel::Table

    我想要ActiveRecord::Relation的理由应该是显而易见的:这是因为我想链接现有的关联并操纵查询以适应不同的目的。

4 个答案:

答案 0 :(得分:34)

几分钟后我使用了where(nil) hack,然后我有了一个脑波,并尝试了一些随机的东西:

User.first.posts.scoped

就是这样! :d

是的,Rails + Arel的记录真的很糟糕。期待它成熟到我可以实际查找并得到实际答案的地步。

答案 1 :(得分:3)

在Rails 4中,使用.scope.spawn来访问关系对象而不是CollectionProxy。请参阅documentation

答案 2 :(得分:1)

通过花时间实际阅读Edge Guides文档,我能够在Section 4.3 has_many Association Reference中找到 答案。简而言之,文档没有说明是否可以获取ActiveRecord::Relation对象或是否正在使用ActiveRecord::Relation对象,但它确实提供了有关如何重用关联并定制其结果的详细信息。

部分4.3.1 Methods Added by has_many列出了 collection .where作为has_many关联添加的方法之一。第4.3.1.11 collection.where(…)部分显示您将使用它,就像使用查询接口的where方法一样。更重要的是,它在集合上使用此方法时提示对象被延迟加载,并且肯定会返回ActiveRecord::Relation对象。

u.posts.where("").class  # => ActiveRecord::Relation
u.posts.where("").to_sql # => SELECT `posts`.* FROM `posts` WHERE `posts`.user_id = 1 

不可否认,这不是理想的解决方案,但它确实给了我一些可以链接的东西。

答案 3 :(得分:1)

ActiveSupport::Concern中,您无法调用私有方法spawn或使用scopescoped

我需要使用它。

where(true)