2 April 2009 · About 2 minutes read

Rails: Setting Default Attributes on an ActiveRecord Model

Update 28 June 2009: Rollo Tomazzi noted in the comments that the method described below will not work for hash-value attributes. He has written a review of the various methods for setting default attribute values on his blog.

Whilst working with Rails’ ActiveRecord, I was looking for a clean way to insert default data into a model object before it was presented to the controller. In a lot of Rails tutorials I’ve seen, such default data is written in the controller, e.g.:

class PostsController < ActionController
  def new
    @post = Post.new(:category_id => 5)
    ...
  end
end

However, this isn’t very DRY, as I would need to duplicate the initialisation code if I were to create an instance of Post in another controller method. It would make more sense to put such default data into the model itself, so that wherever I create the new Post, it is always initialised with the same default data.

I initially thought the answer would be ActiveRecord's after_initialize callback method, but this overwrote any attribute values set from the database after a record was loaded.

Instead, thanks to this post, I learned that you simply override the attribute accessor with a value. You can directly access the dynamic attributes set by ActiveRecord using the read_attribute and write_attribute methods:

class Post < ActiveRecord::Base
  # Default category ID stored in the Settings hash.
  def category_id
    read_attribute(:category_id) or Settings.defaults[:category_id]
  end

  # Hard-coded default
  def title
    read_attribute(:title) or "New Post"
  end
end
Chris Blunt
Chris Blunt @cblunt
Chris is the founder of Plymouth Software. As well as code and business, he enjoys being a Dad, swimming, and the fine art of drinking tea.