代码之家  ›  专栏  ›  技术社区  ›  Richie Thomas

为什么我在“有很多”关系中打电话给“所有者”不起作用?

  •  1
  • Richie Thomas  · 技术社区  · 5 年前

    我使用的是Rails 5.0.7.1,我在 the docs 我的CollectionProxy实例应该有权访问“@owner”实例变量:

    活动记录中的关联代理是对象之间的中间人 它包含被称为@owner的关联和实际的 关联对象,称为@target。什么样的联想 代理大约在@reflection中可用。这是一个例子 类ActiveRecord::Reflection::AssociationReflection。

    blog.posts中的关联代理在blog中的对象为@owner, 其帖子的集合为@target和@reflection对象 表示:有多个宏。

    此类通过方法_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 . 我的期望是不正确的,还是我的代码是错误的,还是完全是其他原因?

    1 回复  |  直到 5 年前
        1
  •  3
  •   mu is too short    5 年前

    文档有点混乱。我记得第一次需要从扩展方法中脱离关联时,我不得不花几个小时猜测、阅读Rails源代码并进行实验来解决这个问题。

    owner proxy_association (这只是 @association ):

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

    我不确定这是“正确”还是“正式”的方式,但这是我自Rails4以来一直在做的事情。