Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What role do ActiveRecord model constructors have in Rails (if any)?

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?

like image 842
John Topley Avatar asked Nov 11 '09 17:11

John Topley


People also ask

What is ActiveRecord in Ruby on Rails?

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.

What does ActiveRecord base do?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.

What is a model in Ruby on Rails?

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.

What is ORM in Ruby on Rails?

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.


2 Answers

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
like image 81
Topher Fangio Avatar answered Nov 05 '22 14:11

Topher Fangio


@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.

like image 39
ashes999 Avatar answered Nov 05 '22 16:11

ashes999