범위 지정
개요
이 가이드 에서는 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가 오류를 발생시키도록 지시할 수 있습니다.
이 설정에 대해 자세히 학습 애플리케이션 구성 가이드 참조하세요.
기본 범위
기본 범위는 대부분의 쿼리에 동일한 기준을 적용 경우에 유용합니다. 기본값 범위를 정의하여 이러한 기준을 모델을 사용하는 모든 쿼리의 기본값 으로 지정할 수 있습니다. 기본 범위는 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 모델을 사용자 지정하는 방법에 대해 자세히 학습 데이터 모델링하기 가이드를 참조하세요.