Rails introduces ActiveRecord::Persistence#update_attribute!
source link: https://blog.saeloun.com/2022/01/27/rails-introduces-update-attribute
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Rails has multiple methods to update a record,
each one reserved for a unique purpose.
While the traditional update
is used to update records by executing validations,
callbacks
and
track changes, there might be a few instances where one would like to skip validations.
Using update_attribute
does just that.
Before
To skip validations on the update,
use update_attribute
that ensures:
- Validations are skipped
- Callbacks are invoked
- updated_at / updated_on column is updated (if that column is available)
- Tracks changes via ActiveModel::Dirty
Let’s look at an example!
class Blog < ApplicationRecord
validates_presence_of :text
before_save :check_if_title_contains_special_characters
def check_if_title_contains_special_characters
throw(:abort) if title.index( /[^[:alnum:]]/ ).present?
end
end
Now let’s compare the differences between update
, update!
and update_attribute
,
> blog = Blog.last
=> #<Blog id: 1, title: "Ruby on Rails Tutorial: Learn Web Development with...", text: nil ... >
> blog.update text: nil
=> false
> blog.update! text: nil
Traceback (most recent call last):
1: from (irb):4
ActiveRecord::RecordInvalid (Validation failed: Text can't be blank)
> blog.update_attribute :text, nil
=> true
As we can see, validations are skipped when using update_attribute
but what is interesting is the behavior of update
and update!
.
While update
silently fails,
calling update!
throws an ActiveRecord::RecordInvalid
error.
Let’s compare callbacks now.
> blog.update title: "Hel@lo"
=> false
> blog.update! title: "Hel@lo"
Traceback (most recent call last):
1: from (irb):10
ActiveRecord::RecordNotSaved (Failed to save the record)
> blog.update_attribute :title, "Hel@lo"
=> false
Now update
and update_attribute
silently fail,
while update!
gives us a better understanding.
Unfortunately, there is no equivalent of update!
for update_attribute
that can
give us insights into record updates.
After
Fortunately, Rails introduces update_attribute! which can be used to prevent “silent” updates.
> blog.update title: "Hel@lo"
=> false
> blog.update! title: "Hel@lo"
Traceback (most recent call last):
1: from (irb):10
ActiveRecord::RecordNotSaved (Failed to save the record)
> blog.update_attribute :title, "Hel@lo"
=> false
> blog.update_attribute! :title, "Hel@lo"
Traceback (most recent call last):
1: from (irb):12
ActiveRecord::RecordNotSaved (Failed to save the record)
This change adds a new method,
ActiveRecord::Persistence#update_attribute!
which calls save!
instead of save
.
The update_attribute!
method will now raise an ActiveRecord::RecordNotSaved
error should any before_*
callbacks throw :abort
.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK