2011-10-19 6 views
2

레일 2.3.9를 사용하고 있습니다. 당신이 #is_a?를 사용하거나 경우에, 그러나# is_a가 아닌 이유는 무엇입니까? ActiveRecord :: NamedScope :: Scope의 인스턴스로 작업하십시오.

Book.has_isbn.class 
# => ActiveRecord::NamedScope::Scope 

: 명명 된 범위의 클래스를 얻을 경우

class Book < ActiveRecord::Base 
    named_scope :has_isbn, :conditions => 'isbn IS NOT NULL' 
end 

, ActiveRecord::NamedScope::Scope가 반환됩니다 문제를 설명하기 위해, 우리는 모델에 명명 된 범위가 가정

Book.has_isbn.is_a?(ActiveRecord::NamedScope::Scope) 
# => false 
ActiveRecord::NamedScope::Scope === Book.has_isbn 
# => false 

이 사람이 왜 이런 일을 알고 있나요 : ===는 범위, 그것은 false 반환 여부를 파악하기 위해? 명명 된 스코프를 호출하면 ActiveRecord::NamedScope::Scope의 인스턴스를 반환합니다 (레일스 코드에서 lib/active_record/named_scope.rb을 보면 리턴 코드가 Scope.new이고 리턴 됨), 왜 #is_a?===true으로 반환되지 않습니까? Scope 클래스

답변

3

체크 아웃 this code :

, 배열에 응답하는 모든 방법 --that [].methods의 모든 방법은

NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?).to_set 
[].methods.each do |m| 
    unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s) 
    delegate m, :to => :proxy_found 
    end 
end 
- Scope 인스턴스에서 정의는 제외 the proxy object에 통과하기 배열은 NON_DELEGATE_METHODS 배열에 정의되어 있습니다. 이것들은 손길이 닿지 않으며 class가 거기에리스트되어 있음을 주목하십시오.

따라서 scope.class으로 전화하면 Scope이 응답으로 표시됩니다. 그러나 scope.is_a?으로 전화하면 실제로는 scope.proxy_found.is_a?이고이 경우 프록시 개체는 Array입니다.

>> scope.is_a?(Array) 
=> true 
+0

아 ... 범위 코드를 볼 때 이것을 놓쳤습니다. 답변 해주셔서 감사합니다! – Claw