I've just been reading this question which is about giving an ActiveRecord model's date field a default value. The accepted answer shows how to set the default value from within the controller. To my mind, this sort of business logic really belongs in the model itself.
Then I got to thinking how if this were Java I'd probably set the initial field value when declaring the instance variable or within the constructor. Since database-backed fields don't have to be explicitly declared within ActiveRecord models, is this something that you could use the model's initialize
method for? I'm curious because I've not really seen much use of constructors for ActiveRecord models within the Rails code that I've looked at. Do they have a role to play and if so, what is it?
Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.
ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.
Models are Ruby classes. They talk to the database, store and validate data, perform the business logic and otherwise do the heavy lifting. They're the chubby guy in the back room crunching the numbers. In this case, the model retrieves video 15 from the database.
Object Relational Mapping (ORM) is the technique of accessing a relational database using an object-oriented programming language. Object Relational Mapping is a way for our Ruby programs to manage database data by "mapping" database tables to classes and instances of classes to rows in those tables.
I do this quite often actually for default values. It works well and still lets the user change it. Remember, the initialize method is called when you say MyObject.new
. However, you may want to read this blog entry (albeit a bit outdated) about using initialize
.
You should use after_initialize
instead of initialize
. The initialize method is required by ActiveRecord::Base to prepare many of the convenience methods. If an after_initialize
method is defined in your model it gets called as a callback to new, create, find and any other methods that generate instances of your model.
Ideally you'd want to define it like this:
def after_initialize
@attribute ||= default_value
end
Also note, you cannot use this callback like the others, you must define a method named after_initialize (like above) for it to work. You can't do the following:
after_initialize :run_some_other_method
@TopherFangio's answer is correct. It seems that the ActiveRecord API changed some time between his answer (2009) and now (2015).
As of today (Rails 4 with ActiveRecord 4.2.0), here's how you add initializers according to the ActiveRecord docs:
class Widget < ActiveRecord::Base
after_initialize |new_widget|
new_widget.name ||= 'Unnamed Widget'
end
end
You can verify with puts
statements or by inspecting the new object from rails console
that it actually initializes correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With