레일즈 : update_attribute vs update_attributes


255
Object.update_attribute(:only_one_field, "Some Value")
Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")

이 두 가지 모두 AR에게 명시 적으로 업데이트하도록 지시하지 않고 객체를 업데이트합니다.

Rails API의 말 :

update_attribute의 경우

일반적인 유효성 검사 절차를 거치지 않고 단일 특성을 업데이트하고 레코드를 저장합니다. 이는 기존 레코드의 부울 플래그에 특히 유용합니다. 유효성 검사 모듈이 혼합되어 있으면 Base의 일반 update_attribute 메서드가이 메서드로 대체됩니다 (기본적으로).

update_attributes를 위해

전달 된 해시에서 모든 속성을 업데이트하고 레코드를 저장합니다. 객체가 유효하지 않으면 저장이 실패하고 false가 반환됩니다.

따라서 객체의 유효성을 검사하지 않으려면 update_attribute를 사용해야합니다. before_save에이 업데이트가 있으면 어떻게됩니까?

내 질문은 update_attribute도 사전 저장 또는 유효성 검사를 무시하는 것입니다.

또한 update_attributes에 해시를 전달하는 올바른 구문은 무엇입니까? 맨 위의 예제를 확인하십시오.


콜백 update_attribute안에 명령문 을 넣고 싶은 이유는 무엇 before_save입니까? 나는 이것에 대한 좋은 이유를 생각할 수 없다.
Daniel Pietzsch

1
업데이트 된 객체의 양에 따라 업데이트 해야하는 객체가 있습니다. 더 좋은 방법은 무엇입니까?
thenengah

업데이트해야 할 객체가 저장하려는 객체의 속성이라는 것이 맞습니까? 그렇다면, 당신은 그것들을 설정할 수 있으며, before_save콜백 내에 설정되기 때문에 어쨌든 저장된 객체와 함께 업데이트됩니다 . update_attribute(:discount, 0.1) if amount > 100당신 대신에 Fe는 할 수있었습니다 discount = 0.1 if amount > 100. update_attribute호출 save명령문이 내부에 있기 때문에,이 경우 불필요한 객체에 before_save콜백 어쨌든 구원을 얻을 것이다. 나는 그것이 의미가 있기를 바랍니다.
Daniel Pietzsch

예, 아니오 그러나 참조하는 오브젝트의 상태는 저장 전에 처리 할 수없는 다른 조건에 따라 달라집니다.
thenengah

3
참고로, 이러한 메소드는 유효성 검사를 건너 뛰지 만 after_save ...와 같은 콜백 을 계속 수행합니다 .
rogerdpack

답변:


328

를 참조하십시오 update_attribute. 소스 표시를 클릭하면 다음 코드가 표시됩니다.

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2614
2614:       def update_attribute(name, value)
2615:         send(name.to_s + '=', value)
2616:         save(false)
2617:       end

이제 update_attributes코드를 참조 하고 살펴보십시오.

      # File vendor/rails/activerecord/lib/active_record/base.rb, line 2621
2621:       def update_attributes(attributes)
2622:         self.attributes = attributes
2623:         save
2624:       end

두 가지의 차이점은 update_attribute용도 save(false)이지만 update_attributes용도 save또는 말할 수 있습니다 save(true).

자세한 설명은 유감이지만 말씀 드리고 싶은 것은 중요합니다. false save(perform_validation = true)인 경우 와 관련된 perform_validation모든 유효성 검사를 무시합니다 (건너 뛰기) save.

두 번째 질문

또한 update_attributes에 해시를 전달하는 올바른 구문은 무엇입니까? 맨 위의 예제를 확인하십시오.

귀하의 예가 맞습니다.

Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")

또는

Object.update_attributes :field1 => "value", :field2 => "value2", :field3 => "value3"

또는 해시의 모든 필드 데이터 및 이름을 얻는다면 params[:user]여기에서 사용하십시오.

Object.update_attributes(params[:user])

7
콜백에 대한 귀하의 진술이 적어도에 잘못되었습니다 Rails 3. 소스의 주석에서 "콜백이 호출됩니다" 라고 매우 명확하게 말합니다 .
Batkins

@Batkins의 말을 두번째로
Raf

3
@Batkins는 여전히 유효성 검사가 실행되지 않습니다-그것이 가장 중요한 부분입니다 :)
Tigraine

1
위의 링크는 더 이상 Rails 5.1 에서 더 이상 정확하지 않습니다 . 이 메소드는 ActiveRecord :: Persistence로 이동되었습니다. 현재 업데이트 된 정보를 찾을 수 있습니다 update 속성 여기가 update_attributes 참고 : update_attributes별칭 지금update
TGF

74

팁 : Commit a7f4b0a1을update_attribute 통해 Rails 4에서 더 이상 사용되지 않습니다 . 찬성하여 제거합니다 .update_attributeupdate_column


45
이것은 더 이상 사실이 아닙니다. 방법이 다시 추가되었습니다. 참조 github.com/rails/rails/pull/6738#issuecomment-39584005
데니스

20
update_attribute검증을 생략하지만,면 콜백은, update_column검증 및 콜백 및 습관 업데이트 모두 건너 뛰고 :updated_at, update모두 콜백 및 검증 존중 정상 함수
무하마드 AbuShady

2
그들은 이미 마음을 구성 할 것입니다. reset_column, update_column도 더 이상 사용되지 않습니다.
ahnbizcad

2
update_column더 이상 사용되지 않지만 update_columns(name: value)선호됩니다. reset_column제거 되었어.
onebree

15

update_attribute

이 메소드는 모델 기반 유효성 검증을 호출하지 않고 오브젝트의 단일 속성을 업데이트합니다.

obj = Model.find_by_id(params[:id])
obj.update_attribute :language, java

update_attributes

이 메소드는 단일 오브젝트의 다중 속성을 업데이트하고 모델 기반 유효성 검증도 전달합니다.

attributes = {:name => BalaChandar”, :age => 23}
obj = Model.find_by_id(params[:id])
obj.update_attributes(attributes)

이 답변이 언제 어떤 활성 기록 방법을 사용해야하는지 명확하게하기를 바랍니다.


12

또한 을 사용하면 지정된 속성 만 업데이트 하는 대량 할당 방법과 달리 업데이트 update_attribute하려는 원하는 속성을 화이트리스트로 표시 할 필요가 없습니다 .attr_accessibleupdate_attributesattr_accessible


8

update_attribute모델의 속성 하나만 업데이트하지만 update_attributes메소드 에서 여러 속성을 전달할 수 있습니다 .

예:

user = User.last

#update_attribute
user.update_attribute(:status, "active")

검증을 통과합니다

#update_attributes
user.update_attributes(first_name: 'update name', status: "active")

유효성 검사에 실패하면 업데이트되지 않습니다.


잘 설명했다. 감사!
Diego Somar 2016 년

6

좋은 답변입니다. 루비 1.9 이상에서는 update_attributes에 새로운 해시 구문을 사용할 수 있습니다 (그리고 생각해야합니다).

Model.update_attributes(column1: "data", column2: "data")

6

속성 또는 업데이트 레코드를 지정하는 모든 가능한 방법 (레일 4로 업데이트 됨) update_attribute, update, update_column, update_columns etc. http://www.davidverhasselt.com/set-attributes-in-activerecord/에 관한이 블로그 게시물을 방문하는 것이 좋습니다. 예를 들어 유효성 검사 실행, 객체의 updated_at 터치 또는 콜백 트리거와 같은 측면에서 다릅니다.

OP의 질문에 대한 답변으로 update_attribute콜백을 전달하지 않습니다.


그래, 나는 대답을 수정했다. 피드백 감사드립니다.
adamliesko

4

update_attributeupdate_attributes유사하지만, 하나 개의 큰 차이 : update_attribute 하지 않습니다 유효성 검사를 실행합니다.

또한:

  • update_attribute단일 속성으로 레코드를 업데이트하는 데 사용됩니다 .

    Model.update_attribute(:column_name, column_value1)
  • update_attributes여러 속성으로 레코드를 업데이트하는 데 사용됩니다 .

    Model.update_attributes(:column_name1 => column_value1, :column_name2 => column_value2, ...)

이 두 가지 방법은 비슷한 이름과 작업으로 인해 혼동하기 쉽습니다. 따라서 update_attribute를 위해 제거되고 update_column있습니다.

이제 Rails4Model.update_column(:column_name, column_value) 에서는 다음 위치에서 사용할 수 있습니다 .Model.update_attribute(:column_name, column_value)

대한 자세한 내용을 보려면 여기클릭하십시오update_column .


4

귀하의 질문에 대답하기 update_attribute위해 사전 저장 "유효성 검사"를 건너 뛰지 만 여전히 다른 콜백을 실행 합니다 after_save. 따라서 실제로 "열을 업데이트하고 AR cruft를 건너 뛰려면"사용해야합니다 (명확하게)

Model.update_all(...)참조 https://stackoverflow.com/a/7243777/32453를


2

최근에 update_attributevs. update_attributes및 유효성 검사 문제가 발생하여 비슷한 이름, 다른 동작, 혼란 스럽습니다.

해시를 전달 update_attribute하고 유효성 검사를 무시하려면 다음을 수행하십시오.

object = Object.new
object.attributes = {
  field1: 'value',
  field2: 'value2',
  field3: 'value3'
}
object.save!(validate: false)

1

귀하의 질문은 before_save에 update_attribute가 있으면 무한 루프가 발생하고 (이전에는 update_attribute 호출에 의해 트리거 된 before_save 콜백의 update_attribute 호출)

실제로 레코드를 저장하지 않기 때문에 before_save 콜백을 우회한다고 확신합니다. 다음을 사용하여 유효성 검증을 트리거하지 않고 레코드를 저장할 수도 있습니다.

Model.save false

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.