我正在使用Rails 5.0.7.1,在the docs中看到我的CollectionProxy实例应该可以访问“ @owner”实例变量:
Active Record中的关联代理是对象之间的中间人 拥有关联(称为@owner)和实际 关联的对象,称为@target。任何一种联想 @reflection中提供了有关proxy的信息。那是 ActiveRecord :: Reflection :: AssociationReflection类。
blog.posts中的关联代理在Blog中的对象为@owner, @post作为其帖子的集合,以及@reflection对象 代表:has_many宏。
此类通过method_missing将未知方法委托给@target。
在我的Rails应用程序中,我有以下(相当不现实)测试代码:
class Post < ApplicationRecord
has_many :comments do
def number_five
if owner.is_a? Post
Comment.where(id: 5, post_id: self.id)
end
end
end
end
class Comment < ApplicationRecord
belongs_to :post
end
当我致电Post.last.commments.number_five
时,出现以下错误:
NameError (undefined local variable or method `owner' for #
<Comment::ActiveRecord_Associations_CollectionProxy:0x00007fcbb9106120>)
当我在byebug
和def number_five
之间的行中添加owner.is_a? Post
并检查self
的值时,我看到它是ActiveRecord::Associations::CollectionProxy
,所以我认为我在应该定义范围的地方调用owner
。
我尝试过Post.last.comments.instance_variables
,但没有看到:@owner
,只有以下内容:
[:@association, :@klass, :@table, :@values, :@offsets,
:@loaded, :@predicate_builder, :@scope]
我也尝试了以下方法:
comments = Post.last.comments
def comments.get_owner
self.owner
end
这将返回与上面相同的NameError
。
关于它的价值,当我运行Post.last.comments.class
时,我看到它是Comment::ActiveRecord_Associations_CollectionProxy
。
考虑到文档的阅读方式,我希望能够从Post.last.comments.owner
(我都尝试过)中调用@owner
或Post.last.comments
,并拥有它返回Post.last
的值。我的期望是不正确的,还是我的代码是错误的,还是完全是其他东西?
答案 0 :(得分:2)
文档有点混乱。我记得我不得不花几个小时进行猜测,阅读Rails的源代码,并尝试弄清楚这一点,这是我第一次需要通过扩展方法摆脱关联。
QDataStream
是您所追求的,但这是关联上的一种方法,您可以通过owner
(这只是proxy_association
的访问器方法)来获得关联:
@association
我不确定这是“正确”还是“官方”方式,但这是我从Rails 4开始就一直在做的事情。