Rails update_attributes는 저장하지 않습니까?


386

레코드를 저장하지 않는 update_attributes에 대한 대안이 있습니까?

그래서 나는 다음과 같은 것을 할 수 있습니다 :

@car = Car.new(:make => 'GMC')
#other processing
@car.update_attributes(:model => 'Sierra', :year => "2012", :looks => "Super Sexy, wanna make love to it")
#other processing
@car.save

BTW, 나는 할 수 있다는 것을 알고 @car.model = 'Sierra'있지만 한 줄로 모두 업데이트하고 싶습니다.


"기록을 저장하지 않는다"는 것은 무엇을 의미합니까?
Anatoly

update_attributes는 모델을 DB에 저장합니다. 그렇지 않은 비슷한 방법이 있는지 궁금합니다.
tybro0103

3
비파괴적인 속성 . 자세한 내용은 API 를 참조하십시오
Anatoly

3
update_column (name, value)을 사용할 수 있습니다. save를 호출하지 않고 객체의 단일 속성을 업데이트합니다. 1. 유효성 검사를 건너 뜁니다. 2. 콜백을 건너 뜁니다. 3. 해당 열이 사용 가능한 경우 updated_at / updated_on 열이 업데이트되지 않습니다. apidock.com/rails/ActiveRecord/Persistence/update_column
Antoine

10
assign_attributes 3.1+의
elado

답변:


597

나는 당신이 찾고있는 것이 믿습니다 assign_attributes.

기본적으로 update_attributes와 동일하지만 레코드를 저장하지 않습니다.

class User < ActiveRecord::Base
  attr_accessible :name
  attr_accessible :name, :is_admin, :as => :admin
end

user = User.new
user.assign_attributes({ :name => 'Josh', :is_admin => true }) # Raises an ActiveModel::MassAssignmentSecurity::Error
user.assign_attributes({ :name => 'Bob'})
user.name        # => "Bob"
user.is_admin?   # => false
user.new_record? # => true

이 줄을 모델에서 붙여 넣지 않았으므로 예제가 약간 오도됩니다. attr_accessible :is_admin, :as => :admin;)
Robin

@Robin 또는 간단히 : attr_protected :is_admin. 또는 : attr_accessible :name이 예에서 : is_admin이 보호되어 있다는 점입니다. 나는 또한으로 보호 된 속성 할당 질량 시도하는 것은주의해야 .assign_attributes참으로 인상 않는 ActiveModel::MassAssignmentSecurity::Error것을이 예에 표시되지 않더라도.
Ajedi32

네,하지만 내 줄은 당신이 연결 한 문서에서 나온 것입니다. 나는 단지 당신이 전체 예제를 복사 / 붙여 넣어야한다고 말하고 있습니다. 그러나 예, 보호되어 있다고 말할 수 있습니다.
Robin

@Robin 예제를 좀 더 구체적으로 업데이트하겠습니다. 문서의 예제 user.assign_attributes({ :name => 'Josh', :is_admin => true })는 오류 메시지가 발생하고 실제로 사용자의 이름 속성을 설정 하지 않는다는 언급이 없기 때문에 약간 오해의 소지 가 있습니다.
Ajedi32

7
assign_attributes는 Rails 3.1부터 사용할 수 있으므로 이전 버전의 Rails를 계속 실행중인 경우 사용할 수 없습니다.
Haegin

173

assign_attributes또는 사용할 수 있습니다 attributes=(동일 함).

업데이트 방법 치트 시트 (레일 6) :

  • update= assign_attributes+save
  • attributes= = 별칭 assign_attributes
  • update_attributes = 사용 중지됨, 별칭 update

출처:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment .rb

다른 치트 시트 :
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet


1
명확하고 짧습니다. 감사.
freemanoid

1
.attributes = val의 경우, 모델이 has_one이고 다른 모델에 대해 accepts_nested_attributes_를 허용하는 경우, 해당 id (모델없이)를 전달하면 (예 : 저장하지 않음) 기존 has_one 모델이 삭제됩니다. 그러나 assign_attributes는 그렇게 동작하지 않습니다.
ClassyPimp

65

'속성'방법을 사용할 수 있습니다.

@car.attributes = {:model => 'Sierra', :years => '1990', :looks => 'Sexy'}

출처 : http://api.rubyonrails.org/classes/ActiveRecord/Base.html

attributes = (new_attributes, guard_protected_attributes = true) 속성 이름과 일치하는 키 (열 이름과 다시 일치)가있는 해시를 전달하여 모든 속성을 한 번에 설정할 수 있습니다.

guard_protected_attributes가 true (기본값) 인 경우 attr_protected 매크로를 사용하여 이러한 형태의 대량 할당으로부터 민감한 속성을 보호 할 수 있습니다. 또는 attr_accessible 매크로를 사용하여 액세스 할 수있는 속성을 지정할 수도 있습니다. 그런 다음 포함되지 않은 모든 속성은 대량 할당 할 수 없습니다.

class User < ActiveRecord::Base
  attr_protected :is_admin
end

user = User.new
user.attributes = { :username => 'Phusion', :is_admin => true }
user.username   # => "Phusion"
user.is_admin?  # => false

user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false)
user.is_admin?  # => true

7

저장하지 않고 ActiveRecord 모델에 값을 대량으로 할당하려면 assign_attributes또는attributes= 메소드를 사용하십시오. 이러한 방법은 Rails 3 이상에서 사용할 수 있습니다. 그러나 알아야 할 사소한 차이점과 버전 관련 문제가 있습니다.

두 방법 모두이 사용법을 따릅니다.

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }

@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }

어떤 메소드도 유효성 검사를 수행하거나 콜백을 실행하지 않습니다. 콜백 및 유효성 검사는save 는 호출 합니다.

레일 3

attributes=assign_attributesRails 3 과 약간 다릅니다. attributes=전달 된 인수가 해시인지 확인하고 그렇지 않으면 즉시 반환합니다. assign_attributes해시 확인이 없습니다. 에 대한 ActiveRecord 속성 할당 API 설명서를attributes= 참조하십시오 .

다음과 같은 잘못된 코드는 속성을 설정하지 않고 단순히 반환하면 자동으로 실패합니다.

@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]

attributes= 과제가 성공적으로 수행 된 것처럼, 실제로는 그렇지 않은 것처럼 자동으로 작동합니다.

이 잘못된 코드는 assign_attributes둘러싸는 배열의 해시 키를 문자열 화하려고 할 때 예외를 발생 시킵니다.

@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])

assign_attributes에 대한 NoMethodError예외 가 발생 stringify_keys하여 첫 번째 인수가 해시가 아님을 나타냅니다. 예외 자체는 실제 원인에 대한 정보가 많지 않지만 예외가 발생한다는 사실은 매우 중요합니다. 중요합니다.

이러한 경우의 유일한 차이점은 대량 할당에 사용 된 방법입니다. attributes=자동으로 성공 assign_attributes하고 오류가 발생했음을 알리는 예외를 발생시킵니다.

이 예제는 생각한 것처럼 보일 수 있지만 어느 정도는 오류가 있지만 API에서 데이터를 변환하거나 일련의 데이터 변환 Hash[]을 사용하고 final의 결과를 잊어 버릴 때 이러한 유형의 오류가 쉽게 발생할 수 있습니다 .map. 위 코드를 50 줄 이상 유지하고 속성 할당에서 3 개의 기능을 제거하면 실패 할 수 있습니다.

Rails 3의 교훈은 이것입니다. 항상assign_attributes 대신에 사용하십시오 attributes=.

레일 4

Rails 4에서는 attributes=단순히에 대한 별칭 assign_attributes입니다. 에 대한 ActiveRecord 속성 할당 API 설명서를attributes= 참조하십시오 .

Rails 4에서는 두 가지 방법을 서로 바꿔 사용할 수 있습니다. 첫 번째 인수로 해시를 전달하지 않으면 매우 유용한 예외가 발생합니다.ArgumentError: When assigning attributes, you must pass a hash as an argument.

검증

을 (를) 준비하기 위해 사전 비행 과제를 수행하는 save경우 저장하기 전에 유효성 검사에 관심이있을 수 있습니다. 이를 위해 valid?invalid?방법을 사용할 수 있습니다 . 둘 다 부울 값을 반환합니다. valid?저장되지 않은 모델이 모든 유효성 검사를 통과하면 true를 반환하고 그렇지 않으면 false를 반환합니다. invalid?단순히 역의valid?

valid? 다음과 같이 사용할 수 있습니다 :

@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?

이를 통해 전화하기 전에 모든 검증 문제를 처리 할 수 ​​있습니다 save.

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