Rails 3.0 - 3.1 / Ruby 1.9.3 and lower

To use default_value_for with older versions of Ruby and Rails, you must use the previous stable release, 2.0.3. This version works with Rails 3.0, 3.1, and 3.2; and Ruby 1.8.7 and higher. It does not work with Rails 4.

gem "default_value_for", "~> 2.0.3"

Rails 2

To use default_value_for with Rails 2.x you must use an older version:

The default_value_for method

The default_value_for method is available in all ActiveRecord model classes.

The first argument is the name of the attribute for which a default value should
be set. This may either be a Symbol or a String.

The default value itself may either be passed as the second argument:

default_value_for :age, 20

...or it may be passed as the return value of a block:

default_value_for :agedoif today_is_sunday?
20else30endend

If you pass a value argument, then the default value is static and never changes. However, if you pass a block, then the default value is retrieved by calling the block. This block is called not once, but every time a new record is instantiated and default values need to be filled in.

The latter form is especially useful if your model has a UUID column. One can generate a new, random UUID for every newly instantiated record:

The difference is purely aesthetic. If you have lots of default values which are constants or constructed with one-line blocks, +default_values+ may look nicer. If you have default values constructed by longer blocks, default_value_for suit you better. Feel free to mix and match.

As a side note, due to specifics of Ruby's parser, you cannot say,

default_value_for :uuid { UuidGenerator.new.generate_uuid }

because it will not parse. One needs to write

default_value_for(:uuid) { UuidGenerator.new.generate_uuid }

instead. This is in part the inspiration for the +default_values+ syntax.

Rules

Instantiation of new record

Upon instantiating a new record, the declared default values are filled into
the record. You've already seen this in the above examples.

Retrieval of existing record

Upon retrieving an existing record in the following case, the declared default values are not filled into the record. Consider the example with the UUID:

What about before_validate/before_save?

True, +before_validate+ and +before_save+ does what we want if we're only interested in filling in a default before saving. However, if one wants to be able to access the default value even before saving, then be prepared to write a lot of code. Suppose that we want to be able to access a new record's UUID, even before it's saved. We could end up with the following code:

What about other plugins?

'Default Value' appears to be unmaintained; its SVN link is broken. This leaves only 'ActiveRecord Defaults'. However, it is semantically dubious, which leaves it wide open for corner cases. For example, it is not clearly specified what ActiveRecord Defaults will do when attributes are protected by +attr_protected+ or +attr_accessible+. It is also not clearly specified what one is supposed to do if one needs a custom +initialize+ method in the model.

I've taken my time to thoroughly document default_value_for's behavior.