Docs Menu

범위 지정

이 가이드 에서는 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 값이 trueBand 에 대한 연결을 포함하는 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

Mongoid는 기본값 범위의 기준을 다른 쿼리 조건과 동일한 방식으로 처리합니다. 이로 인해 ornor 메서드를 사용할 때 놀라운 동작이 발생할 수 있습니다.

다음 예제는 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 모델을 사용자 지정하는 방법에 대해 자세히 학습 데이터 모델링하기 가이드를 참조하세요.