2012-05-03 3 views
3

ActiveRecord 호출에서 관계, 배열 또는 다른 형식을 다시 가져올 지 여부를 알려주는 것은 무엇입니까? 콘솔에 .class를 입력하여 알아낼 수 있다는 것을 알고 있지만, 호출 자체에 내가 묻는 것을 알려주는 무언가가 있습니까?ActiveRecord 쿼리의 반환 형식

+0

결과를 통해 무엇을하려고하는지 알면 도움이됩니다. –

답변

2

는 레일 가끔 거짓말 - 모든 마술사

레일 당신이 당신의 has_many 연결을 체인으로 복잡한 쿼리를 구축 할 수 있습니다 :) 않습니다. 이 기능의 핵심은 XXXAssocation (예 : HasManyAssociation) 클래스입니다. has_many 협회에서 .class으로 전화하면 귀하의 전화는 사실 HasManyAssociation 인스턴스에 적용됩니다. (당신이 정규 표현식에서 볼 수 있듯이, 몇 제외)

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

레일 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 

은 그래서 중요한 것은

  • 할 수 있습니다 체인 범위 및 쿼리 방법,하지만 때까지 첫 번째 또는 전부입니다. 처음 또는 모두 후에는 더 많은 범위와 쿼리 메서드를 호출 할 수 없습니다.
  • 모두를 호출하면 결과 배열이 생성됩니다. 일부 Array 메서드는 데이터베이스에서 작동하도록 재정의되었으므로 반환 된 배열에서 작동하려면 to_a를 호출하십시오. 예를 들어 count입니다. 결과 배열에서 호출 된 경우 배열에서 다시 쿼리 한 경우 배열에있을 레코드 수를 데이터베이스에 쿼리합니다. 당신은 알고