Reputation: 3684
I have a model which stores the details for retail outlets.
In Outlet model I have a before filter
after_save :is_outlet_verified
def is_outlet_verified
if self.latitude.present? && self.longitude.present?
self.update_attributes(:is_verified => true)
else
self.update_attributes(:is_verified => false)
end
end
I want to set is_verified
field to true
if outlet is geocoded. However when is_outlet_verified is successfully executed, it triggers after_save callback which again triggers is_outlet_verified.
Upvotes: 6
Views: 7529
Reputation: 1345
I recently I faced this issue and I solved to use this :)
update_columns(attributes) public
Updates the attributes directly in the database issuing an UPDATE SQL
statement and sets them in the receiver:
user.update_columns(last_request_at: Time.current)
This is the fastest way to update attributes because it goes straight to the database but take into account that in consequence the regular update procedures are totally bypassed. In particular:
Validations
are skipped.
Callbacks
are skipped.
updated_at/updated_on
are not updated.
This method raises an +ActiveRecord::ActiveRecordError+
when called on new objects, or when at least one of the attributes is marked as readonly.
Upvotes: 2
Reputation: 25029
Ideally you would do something like this in a before_save
callback, not after_save
- just set the is_verified
attribute and then just let the save take place as normal.
If you really need to do this, you can use update_column
instead of update_attribute
, which will skip all callbacks.
One caveat to note - if a before_save
callback returns false, then the save will not go ahead.
Upvotes: 19
Reputation: 76774
.update_attributes
invokes the .save
method, so calling it after_save
creates an infinite loop
I'd do it before_save
, like this:
before_save :is_outlet_verified
def is_outlet_verified
if self.latitude.present? && self.longitude.present?
self.is_verified = true
else
self.is_verified = false
end
end
Upvotes: 5
Reputation: 12320
you can use after_create
instead of after_save
to avoid infinte loop occurred by update_attributes
Upvotes: 2