class Record < ActiveRecord::Base
after_initialize do
self.new_flag = some_expression if new_flag.nil?
end
end
However, I was surprised to find out that new_flag will never be nil in this case, because for new model instances Active Record will populate the column attribute with the default DB value, which in this case is true.
The problem with this is that I don’t know how to distinguish this default DB value from user input in a general case. I don’t know if the user has set new_flag to true in a form, or they haven’t set anything and true comes from the DB default.
People sometimes complain Rails is too magical, and I remember some Rails core team members saying they cannot really do anything with this information. So, I wanted to point out a specific example of what I find too magical. For comparison, Sequel doesn’t do this by default, but it has a plugin to get this behavior.
Personally I would argue for having no default in the database and entirely determine the default within Ruby. You are wanting the default to be partially dynamic and partially hard-coded. Seems simpler IMHO to just make it entirely dynamic.
checking .new_record? is definitely the right thing to do here.
You can also look at .changed?
In the case of a new record created with rec = Record.new(new_flag: "x"), .changed? will be true. When you create a record without overriding the default value for new_flag, .changed? will be false
The after_initialize will leave .changed? as false.