ActiveRecord :: Associations :: CollectionProxy从哪里获取.each实例方法?

lyn*_*ynk 5 ruby activerecord ruby-on-rails rails-activerecord

假设我有模型主题和帖子,其中主题has_many:帖子和帖子belongs_to:主题.此时我的数据库中已经有了一些东西.

如果我进入rails控制台并输入

Topic.find(1).posts
Run Code Online (Sandbox Code Playgroud)

我相信我得到了一个CollectionProxy对象.

=> #<ActiveRecord::Associations::CollectionProxy [#<Post id:30, ......>]>
Run Code Online (Sandbox Code Playgroud)

我可以调用.each来获取一个Enumerator对象.

=> #<Enumerator: [#<Post id: 30, ......>]:each>
Run Code Online (Sandbox Code Playgroud)

我很困惑CollectionProxy如何处理.each.我意识到它在某些时候继承了,但我一直在阅读API文档,他们并没有清楚地说明CollectionProxy继承的是什么,除非我遗漏了一些明显的东西.

这个页面似乎没有告诉我太多,这个页面也没有.

Pra*_*thy 6

ActiveRecord::Associations::CollectionProxy 继承自Relation,Relation转发each和许多其他方法to_a.

来自activerecord/lib/active_record/relation/delegation.rb#L45

delegate:to_xml,:to_yaml,:length,:collect,:map,:each,:all?,:include?,:to_ary,:join,to :: to_a

请参阅了解Ruby和Rails:委派以获得有关delegate工作原理的出色解释.


mu *_*ort 6

你为什么不试着问问它从哪里来呢?

> ActiveRecord::Associations::CollectionProxy.instance_method(:each).owner
=> ActiveRecord::Delegation 
Run Code Online (Sandbox Code Playgroud)

方法UnboundMethod#owner

返回定义该方法的类或模块。

所以each来自ActiveRecord::Delegation. 如果你看一下ActiveRecord::Delegation你会看到这个

delegate ..., :each, ... , to: :to_a
Run Code Online (Sandbox Code Playgroud)

所以each进一步下注到to_a.each