Docs Menu
Docs Home
/ / /
몽고이드
/

데이터 작업 수행

이 페이지의 내용

  • 개요
  • 작업 만들기
  • 생성!
  • create
  • save!
  • 저장
  • 읽기 작업
  • 속성
  • 다시 로드
  • 업데이트 작업
  • update_attributes!
  • update_attributes
  • update_attribute
  • 업서트
  • 터치
  • 삭제 작업
  • 삭제
  • 파괴
  • delete_all
  • Destory_all
  • 지속성 속성
  • new_record?
  • 지속되었나요?
  • 필드 값에 액세스
  • 필드 값 가져오기 및 설정
  • read_attribute 및 write_attribute
  • 대량 쓰기 속성
  • 원자 업데이트 연산자
  • 그룹 원자 작업
  • 더티 트래킹(Dirty Tracking)
  • 변경 사항 보기
  • 변경 사항 재설정
  • 지속성
  • 이전 변경 사항 보기
  • 컨테이너 필드 업데이트
  • 읽기 전용 문서
  • 추가 정보

이 가이드 에서는 Mongoid를 사용하여 CRUD (생성, 읽기, 업데이트, 삭제) 작업을 수행하여 MongoDB 컬렉션의 데이터를 수정하는 방법을 학습 수 있습니다.

Mongoid는 Active Record 또는 Data Mapper와 같은 다른 Ruby 매퍼를 사용하여 수행할 수 있는 CRUD 작업을 지원합니다. Mongoid를 사용하는 경우 일반 지속성 작업은 다른 ODM의 경우처럼 매번 전체 문서 데이터베이스 에 쓰는 대신 변경하는 필드에 대해서만 원자성 업데이트를 수행합니다.

만들기 작업을 수행하여 컬렉션 에 새 문서를 추가할 수 있습니다. 컬렉션 존재하지 않는 경우 작업은 암시적으로 컬렉션 만듭니다. 다음 섹션에서는 새 문서를 만드는 데 사용할 수 있는 방법에 대해 설명합니다.

모델 클래스에서 create! 메서드를 사용하여 컬렉션 에 하나 이상의 문서를 삽입합니다. 서버 또는 유효성 검사 오류가 발생하면 create! 에서 예외가 발생합니다.

create!를 호출하려면 삽입하려는 문서 정의하는 속성의 해시를 전달합니다. 여러 문서를 만들고 삽입하려면 해시 배열 을 전달하세요.

이 예시 create!을(를) 호출하는 여러 방법을 보여줍니다. 첫 번째 예시 Person 문서 한 개를 만들고, 두 번째 예시 Person 문서 두 개를 만듭니다. 세 번째 예시 do..end 차단 create!에 전달합니다. Mongoid는 create! 에 전달된 문서를 인수로 사용하여 이 차단 호출합니다. create! 메서드는 차단 의 끝에 문서 저장하려고 시도합니다.

Person.create!(
first_name: "Heinrich",
last_name: "Heine"
)
Person.create!([
{ first_name: "Heinrich", last_name: "Heine" },
{ first_name: "Willy", last_name: "Brandt" }
])
Person.create!(first_name: "Heinrich") do |doc|
doc.last_name = "Heine"
end

데이터베이스 에 새 문서 또는 여러 개의 새 문서를 삽입하려면 create 메서드를 사용합니다. create 은(는) !접미사가 붙은 버전과 달리 유효성 검사 오류에 대해 예외를 발생시키지 않습니다. create 는 중복된 _id 필드 있는 문서 삽입하는 경우와 같이 서버 오류에 대해 예외를 발생시킵니다.

create 에 유효성 검사 오류가 발생하면 문서 삽입되지 않고 삽입된 다른 문서와 함께 반환됩니다. persisted?, new_record? 또는 errors 메서드를 사용하여 데이터베이스 에 삽입된 문서를 확인할 수 있습니다.

이 예시 create 를 사용하여 MongoDB 에 새 문서를 삽입하는 방법을 보여 줍니다. 첫 번째 예시 Person 문서 삽입하는 방법을 보여줍니다. 두 번째 예시 두 개의 Post 문서를 삽입하려고 시도하지만 두 번째 문서 에 중복된 제목이 포함되어 있어 유효성 검사 에 실패합니다. 그런 다음 이 예시 persisted? 메서드를 사용하여 컬렉션 에 성공적으로 삽입된 문서를 확인합니다.

Person.create(
first_name: "Heinrich",
last_name: "Heine"
)
class Post
include Mongoid::Document
validates_uniqueness_of :title
end
posts = Post.create([{title: "test"}, {title: "test"}])
posts.map { |post| post.persisted? } # => [true, false]

persisted? new_record? 및 메서드에 대해 자세히 학습 이 가이드 의지속성 속성 섹션을 참조하세요.

변경된 속성을 컬렉션 에 원자적으로 저장하거나 새 문서 삽입하려면 save! 메서드를 사용합니다. 서버 또는 유효성 검사 검사 오류가 있는 경우 save! 은 예외를 발생시킵니다. new 메서드를 사용하여 새 문서 인스턴스 만들 수 있습니다. 그런 다음 save! 를 사용하여 문서 데이터베이스 에 삽입합니다.

다음 예시 save! 를 사용하여 새 Person 문서 삽입하고 기존 문서 의 first_name 필드 업데이트 방법을 보여 줍니다.

person = Person.new(
first_name: "Esmeralda",
last_name: "Qemal"
)
person.save!
person.first_name = "Malik"
person.save!

save 메서드는 유효성 검사 오류가 있는 경우 예외를 발생시키지 않습니다. save 는 서버 오류가 있는 경우 여전히 예외를 발생시킵니다. 이 메서드는 변경된 속성이 모두 저장되면 true 를 반환하고 유효성 검사 오류가 발생하면 false 를 반환합니다.

다음 옵션을 save에 전달할 수 있습니다.

  • validate: false: 새 문서 또는 업데이트된 속성을 저장할 때 유효성 검사를 우회합니다.

  • touch: false: 지정된 속성을 업데이트할 때 updated_at 필드 업데이트 하지 않습니다. 새 문서 삽입할 때는 이 옵션이 적용되지 않습니다.

다음 코드는 save 을 사용하여 새 문서 삽입합니다. 그런 다음 해당 문서 업데이트하고 validate: false 옵션을 적용합니다.

person = Person.new(
first_name: "Tamara",
last_name: "Graham"
)
person.save
person.first_name = "Aubrey"
person.save(validate: false)

읽기 작업을 수행하여 컬렉션 에서 문서를 조회 수 있습니다. 문서의 하위 집합을 조회 위한 쿼리 필터를 만드는 방법에 대해 자세히 학습 문서 쿼리 지정 가이드 참조하세요.

attributes 메서드를 사용하여 모델 인스턴스 의 속성을 해시로 조회 할 수 있습니다. 이 해시에는 모든 내장된 문서의 속성도 포함됩니다.

다음 예시 attributes을 사용하는 방법을 보여줍니다.

person = Person.new(first_name: "James", last_name: "Nan")
person.save
puts person.attributes
{ "_id" => BSON::ObjectId('...'),
"first_name" => "James",
"last_name" => "Nan"
}

reload 메서드를 사용하여 MongoDB 에서 최신 버전의 문서 에 액세스 할 수 있습니다. 문서 다시 로드하면 Mongoid도 동일한 쿼리 에 포함된 모든 연관 관계를 다시 로드합니다. 그러나 Mongoid는 참조된 연관 관계를 다시 로드하지 않습니다. 대신 다음 번에 액세스 할 때 데이터베이스 에서 로드되도록 이러한 값을 지웁니다.

문서 에서 reload 를 호출하면 문서 에 저장되지 않은 변경 사항이 모두 손실됩니다. 다음 코드는 문서 에서 reload 를 호출하는 방법을 보여줍니다.

band = Band.create!(name: 'Sun 1')
# => #<Band _id: ..., name: "Sun 1">
band.name = 'Moon 2'
# => #<Band _id: ..., name: "Moon 2">
band.reload
# => #<Band _id: ..., name: "Sun 1">

앞의 예시 band 문서 의 name 필드 업데이트하지만 새 값은 저장하지 않습니다. Mongoid가 name 값에 대한 변경 사항을 유지하지 않았기 때문에 name 에는 데이터베이스 에 저장된 원래 값이 포함됩니다.

참고

문서를 찾을 수 없음 오류

Mongoid가 데이터베이스 에서 문서 찾을 수 없으면 기본값 으로 Mongoid::Errors::DocumentNotFound 오류가 발생합니다. mongoid.yml 파일 에서 raise_not_found_error 구성 옵션을 false 로 설정하다 Mongoid가 새 문서 저장하고 해당 속성을 기본값 으로 설정하다 할 수 있습니다. 일반적으로 _id 필드 의 값도 변경됩니다. 이러한 이유로 raise_not_found_errorfalse로 설정하다 경우 reload 를 사용하지 않는 것이 좋습니다.

지속되지 않는 문서 에서 reload 를 호출하면 메서드는 문서의 _id 값에 대해 find 쿼리 수행합니다.

다음 예시 저장되지 않은 문서 에서 reload 를 호출하고 name 필드 값을 출력합니다. reload 는 문서의 _id 값을 사용하여 find 작업을 수행하여 Mongoid가 컬렉션 의 기존 문서 조회 하도록 합니다.

existing = Band.create!(name: 'Photek')
band = Band.new(id: existing.id)
band.reload
puts band.name
Photek

업데이트 작업을 수행하여 컬렉션 의 기존 문서를 수정할 수 있습니다. 삭제된 문서 업데이트 하려고 하면 Mongoid가 FrozenError 예외를 발생시킵니다.

update_attributes! 메서드를 사용하여 기존 모델 인스턴스 의 속성을 업데이트 수 있습니다. 이 메서드는 유효성 검사 또는 서버 오류가 발생하면 예외를 발생시킵니다.

다음 예시 update_attributes! 를 사용하여 기존 문서 의 first_namelast_name 속성을 업데이트 방법을 보여 줍니다.

person.update_attributes!(
first_name: "Maximilian",
last_name: "Hjalmar"
)

Mongoid는 문서 와 문서의 중첩된 연관 관계를 한 번의 호출로 업데이트 할 수 있는 중첩된 속성 기능 제공합니다. 자세히 학습 중첩된 속성 가이드 참조하세요.

update_attributes 메서드는 유효성 검사 오류에 대해 예외를 발생시키지 않습니다. 이 메서드는 유효성 검사 통과하고 문서 업데이트되면 true 를 반환하고, 그렇지 않으면 false 를 반환합니다.

다음 예시 update_attributes을 사용하는 방법을 보여줍니다.

person.update_attributes(
first_name: "Hasan",
last_name: "Emine"
)

메서드를 사용하여 update_attribute 유효성 검사를 우회하고 모델 인스턴스 의 단일 속성을 업데이트 수 있습니다.

다음 예시 update_attribute 를 사용하여 문서의 first_name 속성 값을 업데이트 방법을 보여 줍니다.

person.update_attribute(:first_name, "Jean")

upsert 메서드를 사용하여 문서 업데이트 , 삽입 또는 대체할 수 있습니다.

upsert replace 옵션을 허용합니다. 이 옵션을 true 로 설정하다 하고 upsert 를 호출하는 문서 이미 데이터베이스 에 있는 경우 새 문서 데이터베이스 에 있는 문서를 대체합니다. 새 문서 대체하지 않는 데이터베이스 의 모든 필드는 제거됩니다.

replace 옵션을 false 로 설정하다 하고 문서 데이터베이스 에 존재하는 경우 해당 문서가 업데이트됩니다. Mongoid는 업데이트 문서 에 지정된 필드 이외의 필드는 변경하지 않습니다. 문서 데이터베이스 에 없으면 업데이트 문서 에 지정된 필드 및 값으로 삽입됩니다. replace 옵션은 기본값 으로 false 로 설정하다 됩니다.

다음 예시 upsert 를 사용하여 먼저 새 문서 삽입한 다음 replace: true을 설정하여 대체하는 방법을 보여 줍니다.

person = Person.new(
first_name: "Balu",
last_name: "Rama"
)
person.upsert
person.first_name = "Ananda"
person.upsert(replace: true)

touch 메서드를 사용하여 문서의 updated_at 타임스탬프를 현재 시간으로 업데이트 수 있습니다. touch 는 문서의 belongs_to 연결에 대한 업데이트 계단식으로 진행합니다. 다른 시간 값 필드 옵션으로 전달하여 해당 필드 업데이트 수도 있습니다.

다음 예시 touch 를 사용하여 updated_ataudited_at 타임스탬프를 업데이트 .

person.touch(:audited_at)

삭제 작업을 수행하여 컬렉션 에서 문서를 제거 .

delete 메서드를 사용하여 데이터베이스 에서 문서 삭제 수 있습니다. delete를 사용하는 경우 Mongoid는 콜백을 실행 하지 않습니다. 문서 데이터베이스 에 저장되지 않은 경우 delete 는 동일한 _id 값을 가진 문서 삭제 하려고 시도합니다.

다음 예시 delete 메서드를 사용하는 방법과 데이터베이스 에 저장되지 않은 문서 삭제 어떤 일이 발생하는지 보여 줍니다.

person = Person.create!(name: 'Edna Park')
unsaved_person = Person.new(id: person.id)
unsaved_person.delete
person.reload

앞의 예시 에서, Mongoid는 reload 를 호출할 때 Mongoid::Errors::DocumentNotFound 오류를 발생시킵니다. 그 이유는 두 문서가 _id에 대해 동일한 값을 가지고 있기 때문에 unsaved_person.deleteperson 문서 삭제하기 때문입니다.

destroy 메서드는 destroy를 호출할 때 Mongoid가 콜백을 실행한다는 점을 제외하면 delete와 유사하게 작동합니다. 데이터베이스 에서 문서 찾을 수 없는 경우 destroy 는 동일한 _id를 가진 문서 삭제 하려고 시도합니다.

다음 예시 destroy을 사용하는 방법을 보여줍니다.

person.destroy

delete_all 메서드는 Mongoid 모델 클래스에 의해 모델링된 모든 문서를 컬렉션 에서 삭제합니다. delete_all 은 콜백을 실행 하지 않습니다.

다음 예시 delete_all 을 사용하여 모든 Person 문서를 삭제 방법을 보여 줍니다.

Person.delete_all

destroy_all 메서드는 Mongoid 모델 클래스에 의해 모델링된 모든 문서를 컬렉션 에서 삭제합니다. Mongoid는 모든 문서를 메모리에 로드하기 때문에 비용이 많이 드는 작업이 될 수 있습니다.

다음 예시 destroy_all 을 사용하여 모든 Person 문서를 삭제 방법을 보여 줍니다.

Person.destroy_all

다음 섹션에서는 문서 가 데이터베이스 에 유지되는지 확인하는 데 사용할 수 있는 Mongoid가 제공하는 속성에 대해 설명합니다.

new_record? 속성은 true 모델 인스턴스 아직 데이터베이스 에 저장되지 않은 경우 를 반환하고, 그렇지 false 않으면 를 반환합니다. persisted? 속성으로 반대 조건을 확인합니다.

다음 예시 new_record?을 사용하는 방법을 보여줍니다.

person = Person.new(
first_name: "Tunde",
last_name: "Adebayo"
)
puts person.new_record?
person.save!
puts person.new_record?
true
false

persisted? 속성은 Mongoid가 모델 인스턴스 유지하면 true 를 반환하고, 그렇지 않으면 false 를 반환합니다. new_record? 속성으로 반대 조건을 확인합니다.

다음 예시 persisted?을 사용하는 방법을 보여줍니다.

person = Person.new(
first_name: "Kiana",
last_name: "Kahananui"
)
puts person.persisted?
person.save!
puts person.persisted?
false
true

Mongoid는 문서 의 필드 값에 액세스 할 수 있는 여러 가지 방법을 제공합니다. 다음 섹션에서는 필드 값 액세스 방법을 설명합니다.

문서 에서 필드 값을 가져오고 설정하다 방법에는 여러 가지가 있습니다. 필드 명시적으로 선언하면 문서 에서 직접 이 필드 값을 가져오고 설정하다 수 있습니다. 다음 예시 Person 인스턴스 에 대한 first_name 필드 설정하다 하고 가져오는 방법을 보여 줍니다.

class Person
include Mongoid::Document
field :first_name
end
person = Person.new
person.first_name = "Artem"
person.first_name # => "Artem"

앞의 예시 먼저 first_name 속성을 사용하여 값을 설정하다 다음 다시 호출하여 값을 조회 .

Mongoid 모델 인스턴스 에서 [][] = 메서드를 사용하여 해시 구문을 사용하여 속성에 액세스 수도 있습니다. [] 메서드는 read_attribute 메서드의 별칭이고 [] = 메서드는 write_attribute 메서드의 별칭입니다. 다음 예시 [][]= 메서드를 사용하여 별칭이 지정된 first_name 필드 가져오고 설정하다 방법을 보여 줍니다.

class Person
include Mongoid::Document
field :first_name, as: :fn
end
person = Person.new(first_name: "Artem")
person["fn"]
# => "Artem"
person[:first_name] = "Vanya"
# => "Artem"
person
# => #<Person _id: ..., first_name(fn): "Vanya">

이러한 메서드에 대해 자세히 학습 이 가이드 의 다음 read_attribute 및 write_attribute 섹션을 참조하세요.

read_attributewrite_attribute 메서드를 사용하여 필드를 읽거나 쓸 때 사용자 지정 동작을 지정할 수 있습니다. 모델을 정의할 때 또는 모델 인스턴스에서 호출하여 이러한 메서드를 사용할 수 있습니다.

read_attribute 를 사용하여 필드 가져오려면 필드 이름을 메서드에 전달합니다. write_attribute 를 사용하여 필드 설정하다 하려면 필드 이름과 할당할 값을 전달합니다.

다음 예시 모델 정의에서 read_attributewrite_attribute 를 사용하여 first_namefirst_name=fn 속성을 읽고 쓰기 (write) 데 사용되는 메서드로 정의합니다.

class Person
include Mongoid::Document
def first_name
read_attribute(:fn)
end
def first_name=(value)
write_attribute(:fn, value)
end
end
person = Person.new
person.first_name = "Artem"
person.first_name
# => "Artem"

모델 인스턴스 에서 직접 read_attributewrite_attribute 를 호출하여 속성을 가져오고 설정하다 수도 있습니다. 다음 예시 모델 인스턴스 에서 이러한 메서드를 사용하여 first_name 속성을 가져오고 이를 "Pushkin" 값으로 설정하다 .

class Person
include Mongoid::Document
field :first_name, as: :fn
end
person = Person.new(first_name: "Artem")
# => #<Person _id: ..., first_name(fn): "Artem">
person.read_attribute(:first_name)
# => "Artem"
person.read_attribute(:fn)
# => "Artem"
person.write_attribute(:first_name, "Pushkin")
person
# => #<Person _id: ..., first_name(fn): "Pushkin">

모델 인스턴스 에서 attributes= 또는 write_attributes 메서드를 사용하여 동시에 여러 필드에 쓰기 (write) 수 있습니다.

attributes= 메서드를 사용하려면 모델 인스턴스 에서 메서드를 호출하고 설정하다 하려는 필드와 값이 포함된 해시 객체 전달합니다. 다음 예시 attributes= 메서드를 사용하여 person 문서 에서 first_namemiddle_name 필드를 설정하다 방법을 보여 줍니다.

person.attributes = { first_name: "Jean-Baptiste", middle_name: "Emmanuel" }

write_attributes 메서드를 사용하려면 모델 인스턴스 에서 메서드를 호출하고 설정하다 하려는 필드와 값을 전달합니다. 다음 예시 write_attributes 메서드를 사용하여 person 문서 에서 first_namemiddle_name 필드를 설정하다 방법을 보여 줍니다.

person.write_attributes(
first_name: "Jean-Baptiste",
middle_name: "Emmanuel",
)

Mongoid는 모델 인스턴스에서 메서드로 호출할 수 있는 다음과 같은 업데이트 연산자를 지원 합니다. 이러한 메서드는 작업을 원자적으로 수행하며 유효성 검사 및 콜백을 건너뜁니다.

다음 표에서는 Mongoid에서 지원하는 연산자에 대해 설명합니다.

연산자
설명
예시

add_to_set

배열 값 필드 에 지정된 값을 추가합니다.

person.add_to_set(aliases: "Bond")

bit

필드 의 비트 단위 업데이트 수행합니다.

person.bit(age: { and: 10, or: 12 })

inc

필드 값을 증가시킵니다.

person.inc(age: 1)

pop

배열 필드 의 첫 번째 또는 마지막 요소를 제거합니다.

person.pop(aliases: 1)

pull

배열 필드 에서 지정된 조건과 일치하는 값의 모든 인스턴스를 제거합니다.

person.pull(aliases: "Bond")

pull_all

배열 필드 에서 지정된 값의 모든 인스턴스를 제거합니다.

person.pull_all(aliases: [ "Bond", "James" ])

push

지정된 값을 배열 필드 에 추가합니다.

person.push(aliases: ["007","008"])

rename

일치하는 모든 문서에서 필드 이름을 변경합니다.

person.rename(bday: :dob)

set

Updates an attribute on the model instance and, if the instance is already persisted, performs an atomic $set on the field, bypassing validations.
set can also deeply set values on Hash fields.
set can also deeply set values on embeds_one associations. If a model instance's embeds_one association document is nil, one is created before the update.
set cannot be used with has_one associations.
person = Person.create!(name: "Ricky Bobby")
# Updates `name` in the database
person.set(name: "Tyler Durden")

unset

일치하는 모든 문서에서 특정 필드 삭제합니다.

person.unset(:name)

업데이트 연산자에 대해 자세히 학습 MongoDB Server 매뉴얼에서 업데이트 연산자를 참조하세요.

원자 조작을 함께 그룹 하려면 모델 인스턴스 에서 atomically 메서드를 사용할 수 있습니다. Mongoid는 사용자가 전달하는 모든 작업을 단일 원자 명령으로 atomically 차단 으로 전송합니다.

참고

트랜잭션을 사용하여 여러 문서를 원자적으로 수정하기

원자 조작은 한 번에 하나의 문서 에만 적용 . 따라서 중첩된 atomically 블록은 한 번의 원자 조작 으로 여러 문서를 변경할 수 없습니다. 한 번의 원자 조작 으로 여러 문서를 변경하려면 다중 문서 트랜잭션 사용합니다. 트랜잭션에 대해 자세히 학습 트랜잭션 및 세션 가이드 참조하세요.

다음 예시 atomically 를 사용하여 문서 의 여러 필드를 원자적으로 업데이트 방법을 보여 줍니다.

person.atomically do
person.inc(age: 1)
person.set(name: 'Jake')
end

단일 문서 업데이트할 때 #atomically 블록을 중첩할 수 있습니다. 기본값 으로 Mongoid는 차단 끝날 때 각 차단 에 의해 정의된 원자성 쓰기를 수행합니다. 다음 예시 atomically 블록을 중첩하는 방법을 보여줍니다.

person.atomically do
person.atomically do
person.inc(age: 1)
person.set(name: 'Jake')
end
raise 'An exception'
# Name and age changes are persisted
end

앞의 예시 에서 $inc$set 작업은 내부 atomically 차단 의 끝에서 실행됩니다.

atomically 메서드는 join_context: true 옵션을 허용하여 가장 바깥쪽 atomically 차단 의 끝에서 작업이 실행되도록 지정합니다. 이 옵션을 활성화 하면 가장 바깥쪽 차단 또는 join_contextfalse인 첫 번째 차단 만 데이터베이스 에 변경 사항을 씁니다. 다음 예시 join_context 옵션을 true로 설정합니다.

person.atomically do
person.atomically(join_context: true) do
person.inc(age: 1)
person.set(name: 'Jake')
end
raise 'An exception'
# Name and age changes are not persisted
end

앞의 예시 에서 Mongoid는 가장 바깥쪽 atomically 차단 의 끝에서 $inc$set 작업을 수행합니다. 그러나 차단 종료되고 이러한 작업이 실행 수 있기 전에 예외가 발생하므로 변경 사항이 유지되지 않습니다.

컨텍스트 조인을 전역적으로 활성화 기본값 으로 가장 바깥쪽 atomically 차단 에서 작업이 실행되도록 할 수도 있습니다. 이 옵션을 전역적으로 활성화 하려면 mongoid.yml 파일 에서 join_contexts 구성 옵션을 true 로 설정하다 . Mongoid 구성 옵션에 대해 자세히 학습 자체 관리형 구성 파일 옵션을 참조하세요.

join_contextstrue로 전역 설정하다 하면 atomically 차단 에서 join_context: false 옵션을 사용하여 해당 차단 에 대한 차단 끝에서만 작업을 실행 수 있습니다.

활성 모델에서 사용할 수 있는 것과 유사한 Mongoid API 사용하여 변경된('더티') 필드를 추적 할 수 있습니다. 모델에서 정의된 필드 수정하면 Mongoid가 모델을 더티(dirty)로 표시하고 특수 조치를 수행할 수 있도록 합니다. 다음 섹션에서는 더티 모델과 상호 작용 방법을 설명합니다.

Mongoid는 모델이 새 문서 로 인스턴스화되거나 데이터베이스 에서 검색하여 모델이 인스턴스화될 때부터 저장될 때까지 변경 사항을 기록합니다. 지속성 작업을 수행하면 변경 사항이 지워집니다.

Mongoid는 모델 인스턴스 의 변경 사항을 탐색할 수 있는 모델별 메서드를 생성합니다. 다음 코드는 모델 인스턴스 의 변경 사항을 볼 수 있는 방법을 보여줍니다.

# Retrieves a person instance
person = Person.first
# Sets a new `name` value
person.name = "Sarah Frank"
# Checks to see if the document is changed
person.changed? # true
# Gets an array of changed fields.
person.changed # [ :name ]
# Gets a hash of the old and changed values for each field
person.changes # { "name" => [ "Sarah Frink", "Sarah Frank" ] }
# Checks if a specific field is changed
person.name_changed? # true
# Gets the changes for a specific field
person.name_change # [ "Sarah Frink", "Sarah Frank" ]
# Gets the previous value for a field
person.name_was # "Sarah Frink"

참고

연결 변경 사항 추적

문서 에 연결을 설정해도 changes 또는 changed_attributes 해시는 수정되지 않습니다. 이는 모든 유형의 연결에 해당됩니다. 그러나 참조된 연관 관계의 _id 필드 변경하면 변경 사항이 changeschanged_attributes 해시에 표시됩니다.

다음 코드에 표시된 대로 reset 메서드를 호출하여 변경된 필드 이전 값으로 재설정할 수 있습니다.

person = Person.first
person.name = "Sarah Frank"
# Reset the changed `name` field
person.reset_name!
person.name # "Sarah Frink"

Mongoid는 모든 지속성 작업의 기반으로 더티 추적을 사용합니다. 저장할 때마다 전체 문서 쓰기 (write) 다른 프레임워크와 비교하여 문서 의 변경 사항을 평가하고 변경된 내용만 원자적으로 업데이트합니다. 변경하지 않으면 Model#save을(를) 호출할 때 Mongoid가 데이터베이스 액세스 하지 않습니다.

모델을 MongoDB 에 유지하면 Mongoid가 현재 변경 사항을 지웁니다. 그러나 다음 코드와 같이 previous_changes 메서드를 호출하면 이전에 어떤 변경 사항이 발생했는지 계속 확인할 수 있습니다.

person = Person.first
person.name = "Sarah Frank"
person.save # Clears out current changes
# Lists the previous changes
person.previous_changes
# { "name" => [ "Sarah Frink", "Sarah Frank" ] }

Mongoid에는 현재 Set 또는 Array와 같은 컨테이너 유형의 속성에 대한 변경 사항이 MongoDB 에 저장되지 않는 문제가 있습니다. 컨테이너 유형을 포함한 모든 필드의 값을 MongoDB 에 할당해야 합니다.

예시 들어 Set 다음 코드와 같이 인스턴스 에 항목을 추가해도 변경 사항이 MongoDB 에 유지되지 않습니다.

person = Person.new
person.interests
# => #<Set: {}>
person.interests << 'Hiking'
# => #<Set: {"Hiking"}>
person.interests
# => #<Set: {}> # Change does not take effect

이 변경 사항을 유지하려면 다음 코드에 표시된 대로 모델 외부에서 필드 값을 수정하고 이를 모델에 다시 할당해야 합니다.

person = Person.new
interests = person.interests
# => #<Set: {}>
interests << 'Hiking'
# => #<Set: {"Hiking"}>
# Assigns the Set to the field
person.interests = interests
# => #<Set: {"Hiking"}>
person.interests
# => #<Set: {"Hiking"}>

Mongoid.legacy_readonly 기능 플래그의 값에 따라 다음과 같은 방법으로 문서를 읽기 전용으로 표시할 수 있습니다.

  • 이 플래그가 꺼져 있으면 해당 readonly! 문서 에서 메서드를 호출하여 문서 읽기 전용으로 표시할 수 있습니다. 결과 읽기 전용 문서 저장, 업데이트, 삭제 및 파기를 포함하되 이에 국한되지 않는 지속성 작업을 수행하려고 하면 ReadonlyDocument 오류를 발생시킵니다. 다시 로드해도 읽기 전용 상태 재설정되지 않습니다.

    person = Person.first
    person.readonly? # => false
    person.readonly! # Sets the document as read-only
    person.readonly? # => true
    person.name = "Larissa Shay" # Changes the document
    person.save # => raises ReadonlyDocument error
    person.reload.readonly? # => true
  • 이 플래그가 on로 설정되어 있으면 해당 문서 프로젝트 후 only 또는 without와 같은 메서드를 사용하여 문서 읽기 전용으로 표시할 수 있습니다. 결과적으로 Mongoid에서 ReadonlyDocument 오류가 발생하기 때문에 읽기 전용 문서 삭제 하거나 파기할 수 없지만 저장하고 업데이트 할 수는 있습니다. 문서 다시 로드하면 읽기 전용 상태가 재설정됩니다.

    person = Person.only(:name).first
    person.readonly? # => true
    person.destroy # => raises ReadonlyDocument error
    person.reload.readonly? # => false

    프로젝션

    프로젝션에 대해 자세히 학습 쿼리 결과 수정 가이드 의 지정된 필드 반환 섹션을 참조하세요.

다음 코드와 같이 readonly? 메서드를 재정의하여 문서 읽기 전용으로 만들 수도 있습니다.

class Person
include Mongoid::Document
field :name, type: String
def readonly?
true
end
end
person = Person.first
person.readonly? # => true
person.destroy # => raises ReadonlyDocument error

쿼리 필터 지정에 대해 자세히 학습 문서 쿼리 지정 가이드 를 참조하세요.

모델에 유효성 검사 규칙을 설정하는 방법에 대해 자세히 학습 문서 유효성 검사 가이드 참조하세요.

콜백 정의에 대해 자세히 학습 데이터 모델에 대한 콜백 사용자 지정 가이드 참조하세요.

돌아가기

데이터와 상호 작용