2013-07-09 4 views
0

저는 마이그레이션 프로젝트를 진행 중입니다. 레일즈 2.x 앱을 3.x로 마이그레이션하고 싶습니다. 적극적인 기록에 문제가 있습니다. 레일 2.X에서활성 레코드 클래스

:

arr=StorageUnit.find(:all, :conditions =>"type='Drawer'") 

위의 코드는 나에게 형 서랍 모든 기록을 얻을 것이다. 여기

상기 기능은 중단된다 레일에 3.x

arr.class 
=> Array 

. 그래서 나는 사용해야했다

arr=StorageUnit.where("type='Drawer'") 

위 코드는 Drawer 유형의 모든 레코드를 가져다 줄 것이다.

arr.class 
ActiveRecord::Relation 

내 생각 엔 액티브 레코드가 변경 되었기 때문입니다. 제 문제는이 클래스를 기반으로하는 몇 가지 코드가 있다는 것입니다. 예를 들어

: 그래서 같은 오프

if arr.class== Array 
    do something 
else 
    do something 
end 

는 지금은 더 나은 솔루션이나 그것을 해결하기 위해 어떤 다른 방법이 있는지 알고 그냥 궁금
if arr.class== ActiveRecord::Relation 
    do something 
else 
    do something 
end 

로 변경되었습니다. 나는 그런 물건을 사용한 곳이 많다.

편집 :

arr=StorageUnit.where("type='Drawer'").all 

가 배열로 클래스를 제공합니다. 내 목적은 접미사가없는 코드가 결국 모든 것을 사용하는 것보다 필요한 레코드를 제공 할 수있는 시점을 파악하는 것입니다. 수업을 바꾸는 것 뿐인가? 누군가 ecxplain 수 있습니까?

+0

명시 적으로 사물의 클래스를 확인하는 것은 매우 관용적 인 루비가 아닙니다. –

+0

@FrederickCheung이 정확합니다. 클래스를 절대적으로 검사해야한다면'arr.is_a? (Array) '를 사용할 수 있습니다. –

답변

2

StorageUnit.where은 단순히 ActiveRecord 관계를 반환합니다. .all을 Tacking하면 SQL을 실행하고 StorageUnit의 인스턴스를 생성합니다.

arr = StorageUnit.where(:type => 'Drawer').all 

관계로 반환되는 많은 흥미로운 부작용이 있습니다. 무엇보다도, 당신은 실행하기 전에 범위를 결합 할 수 있습니다 :

StorageUnit.where(:type => 'Drawer').to_sql 

이 상상 : : 이제

class StorageUnit < ActiveRecord::Base 

    scope :with_drawer, where(:type => 'Drawer') 
    scope :with_color, lambda { |c| where(:color => c) } 

end 

:

StorageUnit.with_drawer.with_color('black').first_or_create # return the first storage unit with a black drawer 
StorageUnit.with_drawer.with_color('black').all # return all storage units with black drawers 

StorageUnit.where(:type => 'Drawer').where(:color => 'black') 

가 디버깅에 대한 결과 SQL을 볼 수 있습니다

lation을 사용하면 기본 쿼리를 나중에 사용하기 위해 저장하더라도 빌드 할 수 있습니다. all과 같은 다른 수정자는 관계에 특별한 의미가 있으며 데이터베이스 인스턴스 실행 및 모델 실행을 트리거합니다.

+0

이 경우 클래스가 Array가 될 것이지만 질문이 있습니다. 코드가 없으면 모두를 지정하는 것보다 필요한 레코드를 가져올 수 있습니다. 둘 다 같은 결과를 준다. 하지만 다른 수업. –

+1

'with_drawer'는 람다 일 필요는 없으며, 람다 래퍼가없는'where (: type => 'Drawer') 만 가능합니다; ''클래스 메소드를 사용하는 것이 범위의 인수를 받아들이는 가장 좋은 방법입니다.]] (http://guides.rubyonrails.org/active_record_querying.html#passing-in-arguments) 때문에'with_color'는 클래스 메소드 여야합니다. 그냥 까다 롭다. –

+0

@ mu-is-too-short가 맞다. –