Last Updated: February 25, 2016
·
1.699K
· jcutrell

Rails .save failing silently? Ruby's implicit returns may be your problem.

Say you have a model Blah that has a few values you want to be set to false by default. If you do this in a callback, you could see silent failures left and right. Fix it like this:

class Blah < ActiveRecord::Base
  after_create :send_blah_email
  before_save :default_values

  def default_values
    self.smart ||= true
    self.dumb ||= false
    # remember - this is important, because ruby returns the last statement (in this case, false)
    return true
  end

  def send_blah_email
    BlahMailer.blah_notifier(self).deliver
    #if blah mailer isn't essential, you can do this to make sure things still work out.
    return true
  end
end
```ruby

It's very easy to think, by default, that these callbacks shouldn't be keeping things from happening, but should just work. But, Ruby's implicit return makes the callback return false, which makes the whole call stack return false without actually saving the record. Oh, and no errors are attached to the model, either. (Hence the silent part.)


**Pro Tip**
Of course, you can have a little fun and return some fun string (or anything that doesn't evaluate to false).

1 Response
Add your response

In first example all is caused that your usage of before_save is invalid. You should use after_initialize instead. In second example nicer would be BlahMailer.blah_notifier(self).deliver or true which also always return truth value, but if first statement is successfull then return value returned by that method.

over 1 year ago ·