Ruby on Rails Enumerated Column Constraints

Overview

This is an ROR extension to support enumerations in the database using the enum type in MySQL or column constraints in other databases. Currently only MySQL has been implemented, but other connection adapters can easily be extended to check for column constraints and then parse out the possible values.

This makes it very easy to implement and maintain controlled vocabularies in the database schema without having to change the validations and the view. I have made an effort to make the modifications without modifying the core classes, but I have not been extreamly successful. I have had to make some modifications that are version dependent and then put some exception handlers to make the backward compatible.

This is not the ideal solution and could cause some performance issues in the helpers. The core code still works with both 1.1 and 1.2 without modification. This is schedule to be incorporated into the core for the next major relese.

Installation

To install using the plugin script:

    script/plugin install svn://rubyforge.org/var/svn/enum-column/plugins/enum-column

To manually install using Subversion, do the following. In your vendor/plugins directory, type the following:

    svn checkout svn://rubyforge.org/var/svn/enum-column/plugins/enum-column

Otherwize download the latest zip or tarball and unpack it in your vendor/plugins directory.

How to use it.

In your schema

When you create your schema, specify the constraint as a limit:

  create_table :enumerations, :force => true do |t|
    t.column :severity, :enum, :limit => [:low, :medium, :high, :critical],
       :default => :medium
    t.column :color, :enum, :limit => [:red, :blue, :green, :yellow]
    ...
  end

In the model

You can then automatically validate this column using:

    validates_columns :severity, :color

The rest will be handled for you. All enumerated values will be given as symbols.

    @e = Enumeration.new
    @e.severity = :low

In the views.

In the controller:

   @e = Enumeration.new

The enumerates list of values will be specified as follows:

    <%= input 'e', 'severity' %>

Will create a select/option list:

     <select id="e_severity" name="e[severity]">
     	     <option value="low">low</option>
	     <option value="medium" selected="selected">medium</option>
	     <option value="high">high</option>
	     <option value="critical">critical</option>
     </select>

You can also create a set of radio buttons using the following helper:

    <%= enum_radio('e', 'severity') %=>

Will produce the following group of radio buttons:

    <label>low: <input id="test_severity_low" name="test[severity]" type="radio" value="low" /></label>
    <label>medium: <input checked="checked" id="test_severity_medium" name="test[severity]" type="radio" value="medium" /></label>
    <label>high: <input id="test_severity_high" name="test[severity]" type="radio" value="high" /></label>
    <label>critical: <input id="test_severity_critical" name="test[severity]" type="radio" value="critical" /></label>

You can always use the column reflection to get the list of possible values from the database column.

    Enumeration.columns_hash['color'].values
    
    Will yield: [:red, :blue, :green, :yellow]