개요
Mongoid의 연관 관계를 사용하면 모델 간의 관계를 생성할 수 있습니다. 이 가이드 에서는 참조된 연관 관계를 통해 한 모델이 다른 모델을 참조하는 두 모델 간의 관계 생성하는 방법을 학습 수 있습니다. Mongoid는 다음과 같은 참조 연관 관계 유형을 지원합니다:
has_onehas_manybelongs_tohas_and_belongs_to_many
다음 섹션에서는 이러한 각 연결 유형을 사용하는 방법에 대해 설명합니다.
Has One
has_one 매크로를 사용하여 한 클래스가 나타내는 문서에 별도의 하위 클래스가 나타내는 문서 도 포함되도록 선언할 수 있습니다. 다음 예시 Studio 클래스에 대해 has_one 관계 가진 Band 클래스를 만듭니다.
class Band include Mongoid::Document has_one :studio end
has_one 연관 관계를 선언할 때, 자식 클래스는 반드시 부모 클래스를 참조하는 belongs_to 연관 관계를 사용해야 합니다. 다음 예시 이전 Band 클래스에서 참조된 Studio 클래스를 보여줍니다.
class Studio include Mongoid::Document belongs_to :band end
매크로에 대해 자세히 학습 소속 섹션을 belongs_to 참조하세요.
다음 예시 와 같이 유효성 검사를 사용하여 자식 클래스가 부모 클래스에 있는지 확인할 수 있습니다.
class Band include Mongoid::Document has_one :studio validates_presence_of :studio end
Mongoid의 유효성 검사에 대해 자세히 학습 유효성 검사 가이드 참조하세요.
Has Many
has_many 매크로를 사용하여 클래스가 나타내는 문서에 다른 클래스가 나타내는 하위 문서가 여러 개 포함되어 있음을 선언할 수 있습니다. 다음 예시 Members 클래스에 대해 has_many 관계 가진 Band 클래스를 만듭니다.
class Band include Mongoid::Document has_many :members end
has_many 연관 관계를 선언할 때, 자식 클래스는 반드시 부모 클래스를 참조하는 belongs_to 연관 관계를 사용해야 합니다. 다음 예시 이전 Band 클래스에서 참조된 Member 클래스를 보여줍니다.
class Member include Mongoid::Document belongs_to :band end
매크로에 대해 자세히 학습 belongs_to Belongs To 섹션을 참조하세요.
다음 예시 와 같이 유효성 검사를 사용하여 자식 클래스가 부모 클래스에 있는지 확인할 수 있습니다.
class Band include Mongoid::Document has_many :members validates_presence_of :members end
Mongoid의 유효성 검사에 대해 자세히 학습 유효성 검사 가이드 참조하세요.
연관 관계 정보 조회
데이터베이스 에서 전체 문서 설정하다 를 검색하지 않고도 has_many 연관 관계에 any? 메서드를 사용하여 연관 관계에 문서가 포함되어 있는지 확인할 수 있습니다.
다음 예시 any? 메서드를 사용하여 Band 클래스의 문서에 Members 문서가 포함되어 있는지 확인합니다.
band = Band.first band.members.any?
다음 예시 와 같이 필터하다 와 함께 any? 메서드를 사용하여 지정된 기준과 일치하는 문서를 찾을 수도 있습니다.
band = Band.first band.members.any? { |member| member.instrument == 'piano' }
any? 메서드에 클래스 이름을 제공하여 클래스 이름으로 결과를 필터하다 수 있습니다. 이는 다형성 연관 관계에 유용합니다.
class Drummer < Member end band = Band.first band.members.any?(Drummer)
참고
연결된 클래스의 데이터가 Mongoid에 로드된 후에는 any? 메서드에 대한 후속 호출에서 데이터베이스 쿼리 하지 않습니다. 대신 Mongoid는 메모리에 이미 로드된 데이터를 사용합니다.
exists? 메서드를 호출하여 연결에 영구 문서가 있는지 확인할 수도 있습니다. exists? 메서드는 항상 데이터베이스 쿼리하고 데이터베이스 에 저장된 문서만 확인합니다. exists? 메서드는 필터링을 허용하지 않으며 인수를 허용하지 않습니다.
다음 예시 exists? 메서드를 사용하여 Band 클래스에 지속형 Members 문서가 있는지 확인합니다.
band = Band.create! # Member is not persisted. band.members.build band.members.exists? # Outputs: false # Persist the member band.members.map(&:save!) band.members.exists? # Outputs: true
Belongs To
한 클래스가 나타내는 문서 다른 클래스가 나타내는 문서 의 하위 문서임을 선언하려면 belongs_to 매크로를 사용합니다. 기본값 으로 상위 클래스의 _id 필드 하위 클래스에 저장됩니다. 다음 예시 Band 클래스에 대한 belongs_to 연관 관계가 있는 Members 클래스를 생성합니다.
class Members include Mongoid::Document belongs_to :band end
다음 예시 와 같이 optional 옵션을 true로 설정하여 Mongoid가 연결된 상위 클래스의 _id 를 저장하지 않고도 데이터베이스 에 문서를 유지하도록 할 수 있습니다.
class Members include Mongoid::Document belongs_to :band, optional: true end
팁
애플리케이션의 구성 설정에서 belongs_to_required_by_default 구성 옵션을 false 로 설정하여 상위 클래스가 필요하지 않도록 belongs_to 연관 관계의 기본값 동작을 전역적으로 변경할 수 있습니다.
상위 클래스에서 일치하는 has_one 또는 has_many 연결을 지정하지 않고도 하위 클래스에서 belongs_to 연결을 지정할 수 있습니다. 이렇게 하면 상위 클래스에서 하위 문서 의 필드에 액세스 할 수 없지만 상위 클래스의 _id 필드 와 같이 하위 클래스에 저장된 상위 필드에는 액세스 할 수 있습니다. 다음 예시 에서 Band 클래스는 Members 클래스에 액세스 할 수 없지만 Members 클래스는 Band 클래스에 액세스 할 수 있습니다.
class Band include Mongoid::Document end class Members include Mongoid::Document belongs_to :band end
다음 예시 와 같이 선택적으로 inverse_of 옵션을 nil 로 설정하다 상위 클래스에 하위 클래스에 대한 has_one 또는 has_many 연관 관계가 없음을 나타낼 수 있습니다.
class Band include Mongoid::Document end class Members include Mongoid::Document belongs_to :band, inverse_of: nil end
Has And Belongs To Many
has_and_belongs_to_many 매크로를 사용하여 클래스 모델에 다른 클래스와의 다대다 관계 포함되어 있음을 선언합니다. 다대다 관계 에서는 한 클래스의 각 문서 다른 클래스의 여러 문서와 연결될 수 있습니다. 다음 예시 Members 클래스에 대해 has_and_belongs_to_many 관계 가진 Band 클래스를 만듭니다. Band 문서 여러 개의 Members 문서를 참조할 수 있고, Members 문서 여러 개의 Band 문서를 참조할 수 있습니다.
class Band include Mongoid::Document has_and_belongs_to_many :members end class Members include Mongoid::Document has_and_belongs_to_many :bands end
has_and_belongs_to_many 연결을 선언하면 두 모델 인스턴스 모두 연결된 문서의 _id 값 목록을 저장 . inverse_of 옵션을 nil 로 설정하다 연결된 문서의 _id 값을 모델 인스턴스 중 하나에만 저장 수 있습니다. 다음 예시 Mongoid가 관련 문서의 _id 값을 Band 클래스에만 저장 하도록 합니다.
class Band include Mongoid::Document has_and_belongs_to_many :tags, inverse_of: nil end class Tag include Mongoid::Document end
팁
has_and_belongs_to_many 연관 관계가 있는 문서 업데이트 때, Mongoid는 업데이트된 문서 의 updated_at 필드 설정하지만, 연관된 문서의 updated_at 필드 설정하다 하지 않습니다.
참조된 연관 관계 쿼리
집계 파이프라인 사용하여 참조된 연관 관계 전반에서 문서를 쿼리 할 수 있습니다. 집계 파이프라인 사용하면 여러 컬렉션에 걸쳐 쿼리를 생성하고 데이터를 지정된 형식으로 조작할 수 있습니다. 집계 파이프라인 사용에 대한 자세한 학습 애그리게이션 가이드 참조하세요.
간단한 쿼리의 경우 연관 관계를 직접 쿼리 할 수 있습니다. 컬렉션 에서 직접 쿼리 경우 컬렉션 자체에 있는 필드와 값에 대해서만 쿼리 할 수 있습니다. 쿼리 중인 컬렉션과 연결된 컬렉션은 직접 쿼리 할 수 없습니다.
예시 들어 다음 Band 및 Tour 클래스를 가정해 보겠습니다.
class Band include Mongoid::Document has_many :tours field :name, type: String end class Tour include Mongoid::Document belongs_to :band field :year, type: Integer end
다음 예시 year 값이 2000 이상인 문서에 대해 Tour 클래스를 쿼리하고 해당 문서의 band_id 를 저장합니다. 그런 다음 Band 클래스에 해당 band_id 값을 가진 문서를 쿼리합니다.
band_ids = Tour.where(year: {'$gte' => 2000}).pluck(:band_id) bands = Band.find(band_ids)