2012-05-03 14 views
3

ActiveRecord呼び出しからRelation、Array、または他の型を取得するかどうかを教えてください。私はコンソールに.classをタイプすることができ、それを理解することができますが、私が求めていることを私に知らせる何かがコール自体にありますか?ActiveRecordクエリからの戻り値タイプ

+0

あなたは結果をどうしようとしているのかを知ることは役に立ちます。 –

答えて

2

、Railsは時々あなたにある - すべての手品師は:)

Railsの操作を行い、あなたのhas_many関連をチェーン化することで、複雑なクエリを構築することができます。この機能の核心は、XXXAssocation(例えばHasManyAssociationのような)クラスの束です。 にhas_manyアソシエーションで電話すると、実際にはHasManyAssociationインスタンスに対してコールが適用されます。 (あなたが正規表現で見ることができるように、いくつかを除く)

# collection_proxy.rb 
instance_methods.each { |m| undef_method m unless m.to_s =~ /^(?:nil\?|send|object_id|to_a)$|^__|^respond_to|proxy_/ } 

Railsのundefsを(非表示)HasManyAssociationインスタンスの方法とし、いくつかの基本的な配列に、あなたの呼び出しを渡すために委任とmethod_missingを使用しています。しかし、ここで魔法を開始します

delegate :group, :order, :limit, :joins, :where, :preload, :eager_load, :includes, :from, 
      :lock, :readonly, :having, :pluck, :to => :scoped 

    delegate :target, :load_target, :loaded?, :to => :@association 

    delegate :select, :find, :first, :last, 
      :build, :create, :create!, 
      :concat, :replace, :delete_all, :destroy_all, :delete, :destroy, :uniq, 
      :sum, :count, :size, :length, :empty?, 
      :any?, :many?, :include?, 
      :to => :@association 

    def method_missing(method, *args, &block) 
    match = DynamicFinderMatch.match(method) 
    if match && match.instantiator? 
     send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |r| 
     proxy_association.send :set_owner_attributes, r 
     proxy_association.send :add_to_target, r 
     yield(r) if block_given? 
     end 
    end 

    if target.respond_to?(method) || (!proxy_association.klass.respond_to?(method) && Class.respond_to?(method)) 
     if load_target 
     if target.respond_to?(method) 
      target.send(method, *args, &block) 
     else 
      begin 
      super 
      rescue NoMethodError => e 
      raise e, e.message.sub(/ for #<.*$/, " via proxy for #{target}") 
      end 
     end 
     end 

    else 
     scoped.readonly(nil).send(method, *args, &block) 
    end 
    end 

ので、HasManyAssociationインスタンスはどのようなそれ自体で処理するために、どのような隠された配列を介して行われる必要があると決定した:(あなたの関連付けをチェーン化している場合)(あなたがレコードをフェッチしようとしている場合)、または会合自体に(class方法は、HasManyAssociationに興味がありませんそれでこの隠された配列に呼び出されます。結果は、もちろん、Arrayとなりますが、少し欺瞞です)。

1

私が知っていることが重要だと思われる行に沿って、私の認識があります。これは主にメモリからで、私の頭の上から少しコンソールの実験をしているので、これが周りを回ると改善できるかどうか確信しています。コメントは歓迎され、要求されました。

Derived ActiveRecord class --> Record Instance 
    find 

Derived ActiveRecord class | Relation --> Relation 
    where, select, joins, order, group, having, limit, offset, a scope 

Derived ActiveRecord class | Relation --> Record Instance 
    find 

Derived ActiveRecord class | Relation --> Result Array 
    all 

Result Array --> Array 
    to_a 

だから何が重要なのはあなたがチェーンのスコープとクエリメソッドできますが、最初のまたは全てまで、

  • です。最初またはすべての後に、より多くのスコープとクエリメソッドを呼び出すことはできません。
  • allを呼び出すと、結果配列が得られます。いくつかの配列メソッドはデータベース上で動作するように再定義されています。したがって、返された配列で操作したい場合は、to_aを呼び出します。例はcountであり、Result Arrayで呼び出された場合は、配列が再び照会された場合に、配列に含まれるレコード数をデータベースに問い合わせます。あなたが知っている