关联方法(例如has_many
和belongs_to
定义的关联方法是否会使用ActiveRecord::Relation
?
如果是这样,是否可以获取正在使用的ActiveRecord::Relation
对象。
我们都知道,在使用Query Interface创建查询时,Rails 3在后台大量使用ActiveRecord::Relation
个对象和Arel::Relation
个对象。每当我们使用查询接口的select
,joins
等方法时,都会返回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
的理由应该是显而易见的:这是因为我想链接现有的关联并操纵查询以适应不同的目的。
答案 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
或使用scope
或scoped
。
我需要使用它。
where(true)