为什么我在 "has_many" 关系中对 "owner" 的调用不起作用?

Why is my call to "owner" in a "has_many" relationship not working?

我正在使用 Rails 5.0.7.1,我在 the docs 中看到我的 CollectionProxy 实例应该可以访问“@owner”实例变量:

Association proxies in Active Record are middlemen between the object that holds the association, known as the @owner, and the actual associated object, known as the @target. The kind of association any proxy is about is available in @reflection. That's an instance of the class ActiveRecord::Reflection::AssociationReflection.

the association proxy in blog.posts has the object in blog as @owner, the collection of its posts as @target, and the @reflection object represents a :has_many macro.

This class delegates unknown methods to @target via method_missing.

在我的 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_fiveowner.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

这 return 与上面的 NameError 相同。

就其价值而言,当我 运行 Post.last.comments.class 时,我看到它是 Comment::ActiveRecord_Associations_CollectionProxy

鉴于文档的阅读方式,我希望能够从 Post.last.comments 中调用 Post.last.comments.owner@owner(我都尝试过),并且拥有 return Post.last 的价值。是我的期望不正确,还是我的代码有误,或者完全是其他原因?

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

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

has_many :comments  do
  def number_five
    if proxy_association.owner.is_a? Post
      #...
    end
  end
end

我不确定这是 "right" 还是 "official" 的方法,但这是我从 Rails 4.