[ruby-on-rails] Rails update_attributes는 저장하지 않습니까?

레코드를 저장하지 않는 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'있지만 한 줄로 모두 업데이트하고 싶습니다.



답변

나는 당신이 찾고있는 것이 믿습니다 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


답변

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


답변

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

@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


답변

저장하지 않고 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.


답변