Rails update_attributes沒有保存?

本文翻譯自:Rails update_attributes without save?

Is there an alternative to update_attributes that does not save the record? 有沒有替代update_attributes而不保存記錄的方法?

So I could do something like: 所以我可以做類似的事情:

@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, I know I can @car.model = 'Sierra' , but I want to update them all on one line. 順便說一句,我知道我可以@car.model = 'Sierra' ,但是我想一次全部更新它們。


#1樓

參考:https://stackoom.com/question/SPHC/Rails-update-attributes沒有保存


#2樓

I believe what you are looking for is assign_attributes . 我相信您正在尋找的是assign_attributes

It's basically the same as update_attributes but it doesn't save the record: 它與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

#3樓

You can use assign_attributes or attributes= (they're the same) 您可以使用assign_attributesattributes= (它們相同)

Update methods cheat sheet (for Rails 6): 更新方法備忘單(適用於Rails 6):

  • update = assign_attributes + save update = assign_attributes + save
  • attributes= = alias of assign_attributes attributes= = assign_attributes別名
  • update_attributes = deprecated, alias of update update_attributes =已棄用, update別名

Source: 資源:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb 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 https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment.rb

Another cheat sheet: 另一個備忘單:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet


#4樓

For mass assignment of values to an ActiveRecord model without saving, use either the assign_attributes or attributes= methods. 要在不保存的情況下將值批量分配給ActiveRecord模型,請使用assign_attributesattributes=方法。 These methods are available in Rails 3 and newer. 這些方法在Rails 3和更高版本中可用。 However, there are minor differences and version-related gotchas to be aware of. 但是,需要注意一些細微的差異以及與版本相關的陷阱。

Both methods follow this usage: 兩種方法都遵循這種用法:

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

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

Note that neither method will perform validations or execute callbacks; 注意,這兩種方法都不會執行驗證或執行回調。 callbacks and validation will happen when save is called. 調用save時將發生回調和驗證。

Rails 3 導軌3

attributes= differs slightly from assign_attributes in Rails 3. attributes= will check that the argument passed to it is a Hash, and returns immediately if it is not; attributes=與Rails 3中的assign_attributes略有不同assign_attributes attributes=將檢查傳遞給它的參數是否爲哈希,如果不是,則立即返回;否則,返回false。 assign_attributes has no such Hash check. assign_attributes沒有此類哈希檢查。 See the ActiveRecord Attribute Assignment API documentation for attributes= . 請參閱ActiveRecord屬性分配API文檔以獲取attributes=

The following invalid code will silently fail by simply returning without setting the attributes: 以下無效代碼將通過僅返回而不設置屬性而靜默失敗:

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

attributes= will silently behave as though the assignments were made successfully, when really, they were not. attributes=將默默地表現爲分配已成功完成,實際上卻沒有成功。

This invalid code will raise an exception when assign_attributes tries to stringify the hash keys of the enclosing array: assign_attributes嘗試對封閉數組的哈希鍵進行字符串化時,此無效代碼將引發異常:

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

assign_attributes will raise a NoMethodError exception for stringify_keys , indicating that the first argument is not a Hash. assign_attributes將引發NoMethodError異常stringify_keys ,表明第一個參數是不是哈希。 The exception itself is not very informative about the actual cause, but the fact that an exception does occur is very important. 異常本身並不能很好地說明實際原因,但是異常確實發生的事實非常重要。

The only difference between these cases is the method used for mass assignment: attributes= silently succeeds, and assign_attributes raises an exception to inform that an error has occurred. 這兩種情況之間唯一的區別是用於批量分配的方法: attributes=默默地成功,而assign_attributes引發異常以通知已發生錯誤。

These examples may seem contrived, and they are to a degree, but this type of error can easily occur when converting data from an API, or even just using a series of data transformation and forgetting to Hash[] the results of the final .map . 這些示例在某種程度上似乎是人爲的,但是當從API轉換數據,甚至只是使用一系列數據轉換而忘記將最終.map的結果傳遞給Hash[]時,此類錯誤很容易發生。 。 Maintain some code 50 lines above and 3 functions removed from your attribute assignment, and you've got a recipe for failure. 保持上面的50行代碼和從屬性分配中刪除的3個功能,您將獲得失敗的祕訣。

The lesson with Rails 3 is this: always use assign_attributes instead of attributes= . Rails 3的課程是: 始終使用assign_attributes而不是attributes=

Rails 4 滑軌4

In Rails 4, attributes= is simply an alias to assign_attributes . 在Rails 4中, attributes=只是assign_attributes的別名。 See the ActiveRecord Attribute Assignment API documentation for attributes= . 請參閱ActiveRecord屬性分配API文檔以獲取attributes=

With Rails 4, either method may be used interchangeably. 對於Rails 4,這兩種方法都可以互換使用。 Failure to pass a Hash as the first argument will result in a very helpful exception: ArgumentError: When assigning attributes, you must pass a hash as an argument. 未能將哈希作爲第一個參數傳遞將導致一個非常有用的異常: ArgumentError: When assigning attributes, you must pass a hash as an argument.

Validations 驗證方式

If you're pre-flighting assignments in preparation to a save , you might be interested in validating before save, as well. 如果您在準備save前進行飛行檢查,那麼您可能也有興趣在保存之前進行驗證。 You can use the valid? 您可以使用valid? and invalid? invalid? methods for this. 方法。 Both return boolean values. 兩者都返回布爾值。 valid? returns true if the unsaved model passes all validations or false if it does not. 如果未保存的模型通過所有驗證,則返回true;否則,返回false。 invalid? is simply the inverse of valid? 就是valid?的反函數valid?

valid? can be used like this: 可以這樣使用:

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

This will give you the ability to handle any validations issues in advance of calling save . 這將使您能夠在調用save之前處理所有驗證問題。


#5樓

You can use the 'attributes' method: 您可以使用“屬性”方法:

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

Source: http://api.rubyonrails.org/classes/ActiveRecord/Base.html 來源: http//api.rubyonrails.org/classes/ActiveRecord/Base.html

attributes=(new_attributes, guard_protected_attributes = true) Allows you to set all the attributes at once by passing in a hash with keys matching the attribute names (which again matches the column names). attributes =(new_attributes,guard_protected_attributes = true)允許您通過傳入散列值與屬性名稱匹配(又與列名稱匹配)的鍵來一次設置所有屬性。

If guard_protected_attributes is true (the default), then sensitive attributes can be protected from this form of mass-assignment by using the attr_protected macro. 如果guard_protected_attributes爲true(默認設置),則可以使用attr_protected宏保護敏感屬性免受這種形式的批量分配。 Or you can alternatively specify which attributes can be accessed with the attr_accessible macro. 或者,您也可以指定可以使用attr_accessible宏訪問哪些屬性。 Then all the attributes not included in that won't be allowed to be mass-assigned. 這樣一來,所有未包含在其中的屬性都將無法進行大規模分配。

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章