是否可以获得关联的 ActiveRecord::Relation 对象
Posted
技术标签:
【中文标题】是否可以获得关联的 ActiveRecord::Relation 对象【英文标题】:Is it possible to get the ActiveRecord::Relation object for an association 【发布时间】:2011-05-09 18:27:39 【问题描述】:关联方法(例如has_many
和belongs_to
定义的那些方法)是否使用ActiveRecord::Relation
?
如果可以,是否可以得到正在使用的ActiveRecord::Relation
对象。
我们都知道 Rails 3 在使用Query Interface 创建查询时大量使用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
的理由应该很明显:这是因为我想链接现有的关联并操纵查询以适应不同的目的。
【问题讨论】:
【参考方案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
诚然,这不是理想的解决方案,但它确实给了我一些我可以摆脱的东西。
【讨论】:
【参考方案2】:有几分钟我使用了where(nil)
hack,然后我脑电波并随机尝试了一些东西:
User.first.posts.scoped
就是这样! :D
是的,Rails + Arel 的文档记录确实很差。期待它成熟到我可以实际查找并获得实际答案的程度。
【讨论】:
爱它。干净多了!我给你检查标记。我同意 Arel 文档。我一直在阅读关于它的碎片和碎片。它看起来非常强大,但如果没有良好的文档,它也会很烦人。 :) 有没有办法在我制作的自定义数组上调用.scoped
?
(答案是否定的:scoped
只对***类有意义:/)
有趣的是,.scoped 甚至适用于 has_and_belongs_to_many,否则它会返回一个数组。
.scoped
已折旧【参考方案3】:
在 Rails 4 中,使用 .scope
或 .spawn
而不是 CollectionProxy
来访问关系对象。请参阅documentation。
【讨论】:
【参考方案4】:在ActiveSupport::Concern
中,您不能调用私有方法spawn
或使用scope
或scoped
。
我需要使用它。
where(true)
【讨论】:
以上是关于是否可以获得关联的 ActiveRecord::Relation 对象的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 findAll() 创建查询并通过使用来自 pivot 的 ForeignKey(关系多对多)获得过滤结果?