为什么我在“ has_many”关系中对“所有者”的调用不起作用?

时间:2018-12-30 00:53:36

标签: ruby-on-rails activerecord rails-activerecord

我正在使用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>)

当我在byebugdef 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(我都尝试过)中调用@ownerPost.last.comments,并拥有它返回Post.last的值。我的期望是不正确的,还是我的代码是错误的,还是完全是其他东西?

1 个答案:

答案 0 :(得分:2)

文档有点混乱。我记得我不得不花几个小时进行猜测,阅读Rails的源代码,并尝试弄清楚这一点,这是我第一次需要通过扩展方法摆脱关联。

QDataStream是您所追求的,但这是关联上的一种方法,您可以通过owner(这只是proxy_association的访问器方法)来获得关联:

@association

我不确定这是“正确”还是“官方”方式,但这是我从Rails 4开始就一直在做的事情。