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

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

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

콜백 정의에 대해 자세히 학습 콜백 가이드 참조하세요.

돌아가기

데이터와 상호 작용