96412


`ActiveRecord::Associations::CollectionProxy`で`where`が使えるようですが、ドキュメントに記載がありません。

該当ドキュメント：  
<https://api.rubyonrails.org/v7.0.4/classes/ActiveRecord/Associations/CollectionProxy.html>

ところが、実際に試してみると

[code]

    hoge.foos.class
    
[/code]

の結果は

[code]

    Foo::ActiveRecord_Associations_CollectionProxy
    
[/code]

[code]

    hoge.foos.method(:where)
    
[/code]

の結果は

[code]

    #<Method: Foo::ActiveRecord_Associations_CollectionProxy(ActiveRecord::Associations::CollectionProxy)#where(...) /Users/略/gems/activerecord-7.0.6/lib/active_record/associations/collection_proxy.rb:1114>
    
[/code]

というように whereメソッドが生えているようです。

該当コードは下記だと思います。  
<https://github.com/rails/rails/blob/v7.0.6/activerecord/lib/active_record/associations/collection_proxy.rb#L1105-L1114>

[code]

          delegate_methods = [
            QueryMethods,
            SpawnMethods,
          ].flat_map { |klass|
            klass.public_instance_methods(false)
          } - self.public_instance_methods(false) - [:select] + [
            :scoping, :values, :insert, :insert_all, :insert!, :insert_all!, :upsert, :upsert_all, :load_async
          ]
    
          delegate(*delegate_methods, to: :scope)
    
[/code]

どうやら、QueryMethodでデリゲートしているので(?)、whereが生えていそうです（なんだかややこしいのでほんとにそうなっているかわかりません。雰囲気で読んでいます）。  
デリゲートで生えたメソッドはドキュメントに記載されないものなのでしょうか？

それとも、なにかデリゲートしている項目などが、ドキュメントのどこかに記載されているのでしょうか？  
それとも、根本的になにか見誤っているのでしょうか？


CC BY-SA 4.0
2023-10-03T11:36:40.010
96410
2023-10-04T14:36:23.940
2023-10-03T13:50:35.960
9008
9008
question
ruby-on-rails ruby
ActiveRecord::Associations::CollectionProxy は whereメソッドを持っているがドキュメントに記載がない


Rubyではメタプログラミングによってメソッドが生成されることが多くあります。その際、ドキュメント生成ツールであるRDocの都合上、自動ではドキュメントが生成されないという事情があります（少なくともrailsではそうなっています）。

もちろん、ドキュメントを手書きすることでそれらメソッドにもドキュメントを追加することはできます。しかし、メリットが手間に見合うほど大きくないという判断をされているのだと思います。

railsの世界ではクラスを意識してコードを書くことは少ないため、そのような判断になっている可能性はあります（例えばwhereはチェインできますがその際に返り値のクラスは気にせず同じインターフェースを持つ何かとしてゆるく扱う）


CC BY-SA 4.0
2023-10-03T12:02:11.263
96412
2023-10-03T12:02:11.263
442
96410
answer


ドキュメントがあるかないかで言えばあります。

<https://api.rubyonrails.org/v7.0.4/classes/ActiveRecord/QueryMethods.html#method-
i-where>

一応ActiveRecord::Relation >
activerecord/lib/active_record/relation/query_methods.rb >
ActiveRecord::QueryMethods と辿れないこともないですし、検索で見つけることもできます。

これがCollectionProxyで使えるのは質問の通り委譲の結果なわけですが、リファレンスに乗ってないのはこれに限らずそういうものだと思うしかないです。クラスの定義だけ見ても実際に使えるメソッドが実は他にもあるというのは単純な継承でも発生しうることなので、Railsに限った話でもRubyに限った話でもありません。

(メソッドの実体はあってドキュメントもあるので、少なくとも`where`に関して言えば、「メタプログラミングで生えてるのでドキュメントはない」というのは誤りです)


CC BY-SA 4.0
2023-10-04T14:36:23.940
96424
2023-10-04T14:36:23.940
5793
96410
answer