Ruby on Rails
Enum Column in MySql (Version #20)

Installation

Using the plugin script:

    script/plugin install 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

Otherwise visit:

http://rubyforge.org/projects/enum-column/

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 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]

== comments ==

Cool! This looks like exactly what i want but some people recommend against using the Enum type (I guess for DB portability?) in favor of something else (HowtoUseSetAndEnumColumns) using a varchar type and a buncha validation but that seems like a lot more code. Are there other advantages to NOT using an Enum type? Why not just use this plugin to create simple dropdown type elements for things which don’t need to be updated (ie, values which don’t belong in a table of their own) thanx!
-Anonymous

Enum columns should actually be done by having a referenced table.
-Anonymous

How do you mean?
-Anonymous

They mean that you should do something like :color_id => 5, where in the colors table you have {:id => 5, :name "Yellow"}

- Rails 2.0 patch for PostgreSQL - can the author add this?


Index: init.rb
===============
-- init.rb (revision 1762)
+ init.rb (working copy)
@ -2,6 +2,7 @
require ‘enum/mysql_adapter’ if defined? ActiveRecord::ConnectionAdapters::MysqlAdapter
require ‘enum/postgresql_adapter’ if defined? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
require ‘enum/schema_statements’
require ‘enum/schema_definitions’
require ‘enum/quoting’
require ‘enum/validations’
require ‘enum/active_record_helper’
Index: lib/enum/postgresql_adapter.rb
===============
—- lib/enum/postgresql_adapter.rb (revision 1764)
+
+ lib/enum/postgresql_adapter.rb (working copy)
@ -40,7 +40,7 @
end

def add_column_options!(sql, options)
- unless sql =~ /\(32\)\(‘[^’‘/
+ unless sql =~ /\(32\)\(E?’[^’]
‘/
super(sql, options)
else
sql.gsub!(/(“[^”")([^3]32\))(.+)/, ’\1\2 CHECK’)
Index: lib/enum/schema_definitions.rb
===============
—- lib/enum/schema_definitions.rb (revision 0)
+ lib/enum/schema_definitions.rb (revision 0)
@ -0,0 +1,16 @
+module ActiveRecord
+ module ConnectionAdapters
+ class TableDefinition
+ %w( enum ).each do |column_type|
+ class_eval <<-EOV
+ def #{column_type}(*args)
+ options = args.extract_options!
+ column_names = args
+
+ column_names.each { |name| column(name, ‘#{column_type}’, options) }
+ end
+ EOV
+ end
+ end
+ end
+end

Installation

Using the plugin script:

    script/plugin install 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

Otherwise visit:

http://rubyforge.org/projects/enum-column/

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 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]

== comments ==

Cool! This looks like exactly what i want but some people recommend against using the Enum type (I guess for DB portability?) in favor of something else (HowtoUseSetAndEnumColumns) using a varchar type and a buncha validation but that seems like a lot more code. Are there other advantages to NOT using an Enum type? Why not just use this plugin to create simple dropdown type elements for things which don’t need to be updated (ie, values which don’t belong in a table of their own) thanx!
-Anonymous

Enum columns should actually be done by having a referenced table.
-Anonymous

How do you mean?
-Anonymous

They mean that you should do something like :color_id => 5, where in the colors table you have {:id => 5, :name "Yellow"}

- Rails 2.0 patch for PostgreSQL - can the author add this?


Index: init.rb
===============
-- init.rb (revision 1762)
+ init.rb (working copy)
@ -2,6 +2,7 @
require ‘enum/mysql_adapter’ if defined? ActiveRecord::ConnectionAdapters::MysqlAdapter
require ‘enum/postgresql_adapter’ if defined? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
require ‘enum/schema_statements’
require ‘enum/schema_definitions’
require ‘enum/quoting’
require ‘enum/validations’
require ‘enum/active_record_helper’
Index: lib/enum/postgresql_adapter.rb
===============
—- lib/enum/postgresql_adapter.rb (revision 1764)
+
+ lib/enum/postgresql_adapter.rb (working copy)
@ -40,7 +40,7 @
end

def add_column_options!(sql, options)
- unless sql =~ /\(32\)\(‘[^’‘/
+ unless sql =~ /\(32\)\(E?’[^’]
‘/
super(sql, options)
else
sql.gsub!(/(“[^”")([^3]32\))(.+)/, ’\1\2 CHECK’)
Index: lib/enum/schema_definitions.rb
===============
—- lib/enum/schema_definitions.rb (revision 0)
+ lib/enum/schema_definitions.rb (revision 0)
@ -0,0 +1,16 @
+module ActiveRecord
+ module ConnectionAdapters
+ class TableDefinition
+ %w( enum ).each do |column_type|
+ class_eval <<-EOV
+ def #{column_type}(*args)
+ options = args.extract_options!
+ column_names = args
+
+ column_names.each { |name| column(name, ‘#{column_type}’, options) }
+ end
+ EOV
+ end
+ end
+ end
+end