중첩된 속성
중첩된 속성은 단일 매개변수 해시에 속성을 중첩하여 한 번의 작업으로 문서와 문서의 연관 관계를 업데이트할 수 있는 메커니즘을 제공합니다. 이는 단일 웹 양식 내에서 여러 문서를 편집하려는 경우에 유용합니다.
행동
중첩된 속성은 포함되거나 참조된 모든 연관 관계에 대해 활성화할 수 있습니다. 연결에 대해 이 기능을 활성화하려면 accepts_nested_attributes_for
매크로에 연결 이름을 제공하기만 하면 됩니다.
class Band include Mongoid::Document embeds_many :albums belongs_to :producer accepts_nested_attributes_for :albums, :producer end
참고로 참조된 연관 관계에 중첩된 속성 기능을 추가하면, Mongoid는 자동으로 해당 연관 관계에 대한 자동 저장을 활성화할 것입니다.
연관 관계가 중첩된 속성 동작을 얻으면, 기본 모델에 추가 메서드가 추가되며, 이는 새 기능으로 속성을 업데이트 하는 데 사용해야 합니다. 이 메서드는 연관 관계 이름에 _attributes=
을 더한 것입니다. 이 메서드를 직접 사용할 수도 있고, 더 일반적으로 메서드의 이름이 기본 클래스에 대한 업데이트의 속성이 될 수도 있으며, 이 경우 Mongoid는 내부적으로 적절한 세터를 호출합니다.
band = Band.first band.producer_attributes = { name: "Flood" } band.attributes = { producer_attributes: { name: "Flood" }}
이 기능은 update
, update_attributes
및 attributes=
, create
(및 해당하는 모든 bang 메서드) 등 Mongoid의 모든 속성 기반 세터 메서드에서 작동합니다. 예를 들어, 연결된 주소 레코드로 새 사람을 만드는 것은 다음과 같이 단일 성명서로 수행할 수 있습니다.
person = Person.create( name: 'John Schmidt', addresses_attributes: [ { type: 'home', street: '1234 Street Ave.', city: 'Somewhere' }, { type: 'work', street: 'Parkway Blvd.', city: 'Elsewehre' }, ])
레코드 생성
_id
필드를 생략하여 중첩된 속성을 통해 새 중첩 레코드를 만들 수 있습니다.
person = Person.first person.update(addresses_attributes: [ { type: 'prior', street: '221B Baker St', city: 'London' } ])
이렇게 하면 기존 세트에 새 레코드가 추가됩니다. 기존 기록은 변경되지 않습니다.
기록 업데이트
중첩된 레코드에 _id
필드를 지정하면 속성이 사용되어 해당 ID로 레코드를 업데이트합니다.
person = Person.first address = person.addresses.first person.update(addresses_attributes: [ { _id: address._id, city: 'Lisbon' } ])
해당 ID의 레코드가 없으면 Mongoid::Errors::DocumentNotFound
예외가 발생합니다.
기록 파기
특수 _destroy
속성을 지정하여 이러한 방식으로 레코드를 파기할 수도 있습니다. 이를 사용하려면 accepts_nested_attributes_for
선언과 함께 allow_destroy: true
을 전달해야 합니다.
class Person # ... accepts_nested_attributes_for :addresses, allow_destroy: true end person = Person.first address = person.addresses.first person.update(addresses_attributes: [ { _id: address._id, _destroy: true } ])
업데이트와 마찬가지로 해당 ID의 레코드가 없으면 Mongoid::Errors::DocumentNotFound
예외가 발생합니다.
작업 결합
중첩된 속성을 사용하면 이러한 모든 작업을 단일 문으로 결합할 수 있습니다! 다음은 단일 명령으로 주소를 생성하고, 다른 주소를 업데이트하고, 또 다른 주소를 폐기하는 예입니다.
person = Person.first person.update(addresses_attributes: [ { type: 'alt', street: '1234 Somewhere St.', city: 'Cititon' }, { _id: an_address_id, city: 'Changed City' }, { _id: another_id, _destroy: true } ])