I had a fsck of a time today working with rails. Normally I love Ruby on Rails, but today it gave me the screaming shifts!
I had a model class to which I wanted to add some sensible default values to satisfy some constraints in the database.
The logical place for that was before_create, so I did something like the following
class MyModel < ActiveRecord::Base
def before_create
self.foo ||= true
self.bar ||= Time.now
self.baz ||= false
end
end
Now, I would have thought that would work, but whenever I tried to save an instance of my class to the database the save method would return false 🙁
Hmmmm. Ok, let’s add some logging code and see what the problem is… Are there any errors? Nope. Does the instance think it’s valid? Yes. OK, that’s weird. Maybe there is something going on and the exception is getting eaten by some other code in the application (there are three of us working on this code and we’re not all in the same state, so who knows what one of the others may have done 😉 ). I try creating an instance using the rails console. Same thing (which is to be expected, but I was starting to get a little desperate by this stage).
What was the next thing to do? Go through the code and remove things line by line until I start getting some exceptions. Finally in desperation I took out my before_create method, and lo and behold my error messages come back. It was then that I was struck by the thought that Ruby methods take their return value from the last expression evaluated in their body, so the before_create method was returning false. It seems that there is a nice undocumented “feature” in ActiveRecord that allows application code to stop an object being saved to the database by returning false from before_create, and I imagine before_save.
A little note to that affect in the documentation would have saved me quite a bit of time today.
Ah well. Live and learn I guess 🙂