개요
이 가이드 에서는 Mongoid 모델에 범위 를 구현 방법을 학습 수 있습니다. 범위는 일반적인 필터하다 기준을 재사용할 수 있는 편리한 방법을 제공합니다. 필터하다 기준 만들기에 대해 자세히 학습 문서 쿼리 지정 가이드 참조하세요.
대부분의 쿼리에 동일한 기준을 적용하는 경우 애플리케이션 에 범위를 구현 반복되는 코드를 줄일 수 있습니다.
명명 범위
명명된 범위는 제공된 이름으로 참조되는 클래스 로드에서 정의된 기준입니다. 필터하다 기준과 유사하게, 이 기준은 지연 로드되고 체인이 가능합니다.
이 예시 다음과 같은 명명된 범위를 포함하는 Band 모델을 정의합니다.
japanese:country필드 의 값이"Japan"인 문서와 일치합니다.rock:genre필드 값에"rock"가 포함된 문서와 일치합니다.
class Band include Mongoid::Document field :country, type: String field :genres, type: Array scope :japanese, ->{ where(country: "Japan") } scope :rock, ->{ where(:genres.in => [ "rock" ]) } end
그런 다음 명명된 범위를 사용하여 쿼리 할 수 있습니다. 다음 쿼리 명명된 범위를 사용하여 country 필드 값이 "Japan" 이고 genre 필드 값에 "rock"가 포함된 문서를 일치시킵니다.
Band.japanese.rock
고급 범위 지정
매개 변수를 허용하고 기능을 확장하도록 명명된 범위에서 Proc 객체 및 블록을 정의할 수 있습니다.
이 예시 country 필드 값이 매개변수로 전달된 지정된 값인 문서와 일치하는 based_in 범위를 포함하는 Band 모델을 정의합니다.
class Band include Mongoid::Document field :name, type: String field :country, type: String scope :based_in, ->(country){ where(country: country) } end
그런 다음 다음 코드에 표시된 대로 based_in 범위를 사용하여 쿼리 할 수 있습니다.
Band.based_in("Spain")
Mongoid를 사용하면 다음 예시 와 같이 기존 클래스 메서드를 숨기는 범위를 정의할 수 있습니다.
class Band include Mongoid::Document def self.on_tour true end scope :on_tour, ->{ where(on_tour: true) } end
범위가 기존 클래스 메서드를 덮어쓸 때 scope_overwrite_exception 구성 옵션을 true로 설정하여 Mongoid가 오류를 발생시키도록 지시할 수 있습니다.
이 설정에 대해 자세히 학습 MongoDB 에 연결 가이드 참조하세요.
기본 범위
기본 범위는 대부분의 쿼리에 동일한 기준을 적용 경우에 유용합니다. 기본값 범위를 정의하여 이러한 기준을 모델을 사용하는 모든 쿼리의 기본값 으로 지정할 수 있습니다. 기본 범위는 Criteria 객체를 반환합니다.
기본값 범위를 만들려면 모델 클래스에서 default_scope 메서드를 정의해야 합니다.
다음 코드는 active 필드 값이 true인 문서만 조회 하도록 Band 모델의 default_scope 메서드를 정의합니다.
class Band include Mongoid::Document field :name, type: String field :active, type: Boolean default_scope -> { where(active: true) } end
그런 다음 Band 모델에 대한 모든 쿼리는 active 값이 true인 문서를 사전 필터링합니다.
필드 초기화
기본값 범위를 지정하면 새 모델의 필드가 기본값 범위에 지정된 값(예: 부울 값이나 정수)인 리터럴인 경우 해당 값으로 초기화됩니다.
참고
필드 및 범위 충돌
필드 정의와 기본값 범위에서 기본값 을 제공하면 다음 예시 와 같이 기본값 범위의 값이 우선합니다.
class Band include Mongoid::Document field :name, type: String field :on_tour, type: Boolean, default: true default_scope ->{ where(on_tour: false) } end # Creates a new Band instance in which "on_tour" is "false" Band.new
기본값 범위의 중첩 필드를 참조할 때는 점 표기법 사용하지 않는 것이 좋습니다. 이렇게 하면 Mongoid가 새 모델에서 예기치 않은 필드를 초기화하도록 지시할 수 있습니다.
예시 들어, tour.year 필드 참조하는 기본값 범위를 정의하는 경우 새 모델은 year 필드 포함하는 중첩 객체 로 tour 필드 대신 tour.year 필드 로 초기화됩니다.
쿼리할 때 Mongoid는 점 표기법 올바르게 해석하고 중첩된 필드 에 지정된 값이 있는 문서를 일치시킵니다.
연관 관계
연결의 일부인 모델에 기본값 범위를 정의하는 경우 범위 지정을 다시 적용하려면 연결을 다시 로드해야 합니다. 이는 범위가 적용될 때 가시성에 영향을 미치는 연관 관계의 문서 값을 변경할 때 필요합니다.
이 예시 다음 모델을 사용합니다.
class Label include Mongoid::Document field :name, type: String embeds_many :bands end class Band include Mongoid::Document field :name, type: String field :active, default: true embedded_in :label default_scope ->{ where(active: true) } end
active 값이 true인 Band 에 대한 연결을 포함하는 Label 모델을 생성한다고 가정해 보겠습니다. active 필드 false로 업데이트 Mongoid는 기본값 범위에도 불구하고 여전히 이를 로드합니다. 범위가 적용된 연결의 문서를 보려면 reload 연산자 호출해야 합니다.
다음 코드는 이 시퀀스를 보여줍니다.
label = Label.new(name: "Hello World Records") band = Band.new(name: "Ghost Mountain") label.bands.push(band) label.bands # Displays the Band because "active" is "true" band.update_attribute(:active, false) # Updates "active" to "false" # Displays the "Ghost Mountain" band label.bands # => {"_id":"...","name":"Ghost Mountain",...} # Won't display "Ghost Mountain" band after reloading label.reload.bands # => nil
or andnor 쿼리 동작
Mongoid는 기본값 범위의 기준을 다른 쿼리 조건과 동일한 방식으로 처리합니다. 이로 인해 or 및 nor 메서드를 사용할 때 놀라운 동작이 발생할 수 있습니다.
다음 예제는 Mongoid가 기본값 범위를 가진 모델에 대한 쿼리를 해석하는 방법을 보여줍니다.
class Band include Mongoid::Document field :name field :touring field :member_count default_scope ->{ where(touring: true) } end # Combines the condition to the default scope with "and" Band.where(name: 'Infected Mushroom') # Interpreted query: # {"touring"=>true, "name"=>"Infected Mushroom"} # Combines the first condition to the default scope with "and" Band.where(name: 'Infected Mushroom').or(member_count: 3) # Interpreted query: # {"$or"=>[{"touring"=>true, "name"=>"Infected Mushroom"}, {"member_count"=>3}]} # Combines the condition to the default scope with "or" Band.or(member_count: 3) # Interpreted query: # {"$or"=>[{"touring"=>true}, {"member_count"=>3}]}
쿼리 시 범위 비활성화
다음 예제와 같이 unscoped 연산자 사용하여 Mongoid가 기본값 범위를 적용 않도록 지시할 수 있습니다.
# Inline example Band.unscoped.where(name: "Depeche Mode") # Block example Band.unscoped do Band.where(name: "Depeche Mode") end
런타임 시 기본 범위 재정의
with_scope 메서드를 사용하여 런타임에 차단 의 기본값 범위를 변경할 수 있습니다.
다음 모델은 명명된 범위 를 mexican 정의합니다.
class Band include Mongoid::Document field :country, type: String field :genres, type: Array scope :mexican, ->{ where(country: "Mexico") } end
다음 코드와 같이 with_scope 메서드를 사용하여 mexican 명명 범위를 런타임에 기본값 범위로 설정하다 수 있습니다.
Band.with_scope(Band.mexican) do Band.all end
클래스 메서드
Mongoid는 Criteria 객체를 반환하는 클래스 메서드를 범위로 처리합니다. 다음 예시 와 같이 이러한 클래스 메서드를 사용하여 쿼리 할 수 있습니다.
class Band include Mongoid::Document field :name, type: String field :touring, type: Boolean, default: true def self.touring where(touring: true) end end Band.touring
추가 정보
Mongoid 모델을 사용자 지정하는 방법에 대해 자세히 학습 데이터 모델링하기 가이드를 참조하세요.