rails 3 : Do i need to give return true in a before_save callback for an object.save to work?
From: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks defined as methods on the model, which are called last.
So, yes.
Rails 3: Ensure before_save callback is called after others
You could make the callback you want executed last an around_save
callback. Check out the list of available callbacks and see if you can simply use a different callback "bucket" for some of your callbacks to ensure they are executed in the desired order.
If you still end up with multiple before_save
callbacks and need one to trigger last, you may want to create custom callbacks, like maybe define_model_callbacks :split_save
, registering your regular before_save
callbacks as before_split_save
callbacks, the one you want executed last as a after_split_save
callback, and then just a single before_save
callback that runs those two groups of callbacks (run_callbacks :split_save
). See ActiveModel::Callbacks
for more on how to do this.
before save callback for boolean field
The reason for the error is that before_save
hooks have the ability to cancel save operation by returning false
(which is what happens when your record is not expired.
Return something else, not result of the assignment. For example:
def update_availabiltiy
self.expired = date_end.to_date < Date.today
true # no canceling
end
Rails 4: How to cancel save on a before_save callback?
To prevent record from being saved, you should simply return false
:
def check_for_similar_record
if ProductsColor.exists?(color_id: self.color_id, product_id: self.product_id)
# merge values
false
else
true
end
end
Is there a way to make a before_save conditional?
you can use :if
before_save do_something, :if => Proc.new {|model| model.some_boolean_attr_or_method }
or simply
before_save do_something, :if => some_condition
EDIT:
for a quick reference, there's an excellent guide about this:
http://guides.rubyonrails.org/active_record_callbacks.html#conditional-callbacks
record not saving when before_save action is called
In versions of Rails prior to 5.0.0, returning false from a callback method will cancel the save. From the Rails 4.2.7 documentation:
If a before_* callback returns false, all the later callbacks and the
associated action are cancelled. Callbacks are generally run in the
order they are defined, with the exception of callbacks defined as
methods on the model, which are called last.
When setting self.three_speed = false
, it is the last statement that is run in the method, so that false is the return value of the assign_three_speed method. That's why adding the logger to the last line fixed it. Have the method return some other value instead.
Return true as the last line if you never want to cancel the callback:
def assign_three_speed
if CreateFulfillmentService::NON_US_MARKETPLACES.include(self.marketplace)
self.three_speed = false
else
self.three_speed = true
end
true
end
Rails 5 - conditional before_save callback on belongs_to existence when relation is optional
before_save :set_status, if: :template_exists?
def template_exists?
return !self.template.nil?
end
^ This method works because the callback needs code that it can execute at runtime. You can pass it a symbol or string that maps to the name of a method, or you can pass it a proc or lambda that it can execute at runtime. But if you pass it code like
before_save :set_status, if: self.template.nil?
then it will actually try to execute that code at the time when you are setting up the callback, not at the time when the callback is called. When you are setting up the callback, self
refers to the class Card
not the instance of the class.
Here's some documentation on ActiveRecord callbacks if you want more detail.
Related Topics
How to Return Everything After Last Slash(/) in a Ruby String
Using %I and %I Symbol Array Literal
How to Specify a Minimum Ruby Version in a Gemspec
Truncate a Floating Point Number Without Rounding Up
Error Installing JSON 1.8.3 with Ruby 2.4
Ruby Syntax: Break Out from 'Each.. Do..' Block
How to Host a Rails Web Application
Is There an Easy-To-Use Ftp Library for Ruby
Setting the Environment in Gemfile for Bundling Install/Update Based on a Customize File
Hash Remove All Except Specific Keys
Running a Shell Command from Ruby: Capturing the Output While Displaying the Output
What Ide/Editor Do You Use for Ruby on Linux
How to Best Create a Random Float in a Range Between Two Floats