Ruby on Rails
MagicFieldNames

Rails values convention over configuration. This is also true in the realm of table design where fields given particular names automatically gain certain behaviours. For a walkthrough of how to add your own behaviours like the ones below, see the ExtendingActiveRecordExample and by+and+updated_by" class="existingWikiWord">Howto Add created_by and updated_by._

List of Magic Field Names

What do they do?

Timestamping

Active Record will automatically record creation and/or update timestamps of database objects if fields named created_at/created_on or updated_at/updated_on are present.

More about Timestamping, API docs for Timestamp

Optimistic Locking

Active Records support optimistic locking if the field lock_version is present. Optimistic Locking requires that at least one item in the model requires uniqueness validation (e.g. validates_uniqueness_of :foo). If you don’t have validates_uniqueness_of you will run into call back errors.

Ensure that the attribute lock_version is passed in and can be evaluated between conflicting posts. i.e. put it in your view as a hidden field.

API documentation for Locking

Single table inheritance

Active Record allows inheritance by storing the name of the class in a column that by default is called “type” (can be changed by overwriting Base.inheritance_column).

See the Single table inheritance section of the Active Record API docs.

Primary Key

All model tables require a primary key. The key is assumed to be named id, but this default can be changed with the methods set_primary_key or primary_key. See \ActiveRecord:Base for more details.

NOTE: Primary keys CAN NOT be text fields! Rails, as of the time I’m inputting this edit, requires a primary id field to be an integer. So – you are forced to use surrogate or composite keys.
- Jabberwock

Counter Cache

The associations belongs_to can (optionally) make use of a counter cache. This caches the number of belonging objects on the associated class. This requires that a column named “#{table_name}_count” (such as comments_count for a belonging Comment class) is used on the associate class (such as a Post class).

Ex:


class Post < ActiveRecord::Base belongs_to :author, :counter_cache => true end

If you want to specify the count field, use


:counter_cache => :my_custom_counter

Note: This feature does not make parent.child.count/length use this cache, instead, a COUNT query is used.

API documentation for Associations

I spent the better part of a day trying to figure out why my counter cache wasn’t working. As it turns out you need to initialize the counter by specifying a default value of 0 when defining the field in the database. The increment_counter code looks like this:


# File vendor/rails/activerecord/lib/active_record/base.rb, line 525
525:       def increment_counter(counter_name, id)
526:         update_all "#{counter_name} = #{counter_name} + 1", "#{primary_key} = #{quote_value(id)}"
527:       end

I would expect the database to throw an error when trying to perform a null + 1 operation. Apparently MySQL just ignores it and the field remains null.

Acts as List

This act provides the capabilities for sorting and reordering a number of objects in a list. The class that has acts_as_list specified needs to have a “position” column defined as an integer on the mapped database table.

API documentation for acts_as_list

Acts as Tree

Used where you want to model a tree-structure by providing a parent association and an children association. This act assumes that your model has a foreign key column, which by default is called parent_id.

API documentation for acts_as_tree

Acts as Nested Set

This acts_as_ provides Nested Set functionality. Nested Set is similiar to Tree, but with the added feature that you can select the children and all of its descendents with a single query. This act assumes that your model has a foreign key column, which by default is called parent_id as well as a left(@lft@) and a right(@rgt@) column.

API documentation for acts_as_nested_set

category: Glossary