How (replace | create) an enumeration field on rail 2.0 routes?

I would like to create an enum field with sone migration, which I do, I tried searching on google but cannot find a way to do this in migration

The only thing I found is

t.column :status, :enum, :limit => [:accepted, :cancelled, :pending] 

but it looks like the above code only works on rails 1.xxx, and since I am running rails 2.0

this is what i tried but it fails

 class CreatePayments < ActiveRecord::Migration def self.up create_table :payments do |t| t.string :concept t.integer :user_id t.text :notes t.enum :status, :limit => [:accepted, :cancelled, :pending] t.timestamps end end def self.down drop_table :payments end end 

So, if this is not allowed, what do you think might be a good solution? just a text box and confirmation from the model?

+28
ruby ruby-on-rails migration
Mar 29 '09 at 1:18
source share
10 answers

You can manually specify the type using the t.column method. Rails interprets this as a string column, and you can simply add a validator to the model, as Paul suggested:

 class CreatePayments < ActiveRecord::Migration def self.up create_table :payments do |t| t.string :concept t.integer :user_id t.text :notes t.column :status, "ENUM('accepted', 'cancelled', 'pending')" t.timestamps end end def self.down drop_table :payments end end class Payment < ActiveRecord::Base validates_inclusion_of :status, :in => %w(accepted cancelled pending) end 
+36
Jul 09 '09 at 10:40
source share

Look at tip # 3 at http://zargony.com/2008/04/28/five-tips-for-developing-rails-applications

This is exactly what you need!

  class User < ActiveRecord::Base validates_inclusion_of :status, :in => [:active, :inactive] def status read_attribute(:status).to_sym end def status= (value) write_attribute(:status, value.to_s) end end 

NTN

+24
May 12 '09 at 8:36 a.m.
source share

You can try the (very) comprehensive jeff enumerated_attribute gem OR go with this simple workaround:

 class Person < ActiveRecord::Base SEX = [:male, :female] def sex SEX[read_attribute(:sex)] end def sex=(value) write_attribute(:sex, SEX.index(value)) end end 

And then declare the sex attribute as an integer:

 t.integer :sex 

This worked very well for me! = D

+9
Aug 12 '09 at 0:00
source share

I have dozens of these small listings, with 3-300 entries each. I implement them as lookup tables. I do not have a model file for each of them; I use metaprogramming to create a model for everyone, since each table has the same set of columns (id, name, description).

Since some of the sets had enough elements to guarantee their own table, it would be more consistent to move them all to tables. Another option if you have more of these listings later.

EDIT: Here I create the models:

 ACTIVE_RECORD_ENUMS = %w{ AccountState ClientType Country # ... } ACTIVE_RECORD_ENUMS.each do |klass| eval "class #{klass} < ActiveRecord::Base; end" klass.constantize.class_eval do class << self def id_for(name) ids[name.to_s.strip.humanize.downcase] end def value_for(id) values[id.to_i] end def values @values ||= find(:all).inject({}) {|h,m| h[m.send(primary_key)] = m.name; h} end def ids @ids ||= self.values.inject({}) {|h, {k, v}| h[v.downcase] = k; h} end end end end 

This file is located in the models directory and is included in application_config.rb . This allows me to do things like this:

 AccountState.ids # => {"active" => 1, "deleted" => 2} AccountState.values # => {1 => "Active", 2 => "Deleted"} AccountState.id_for("Active") # => 1 AccountState.value_for(1) # => "active" 
+4
Mar 29 '09 at 10:11
source share

Have you seen the enum-column plugin on RubyForge?

+3
Apr 10 '09 at 13:11
source share

Similarly, an enumerated_attribute gem manages object-level enumerations.

 enum_attr :status, %w(accepted cancelled ^pending) 

Define a string in migration

 t.string :status 

Also provides some interesting features, such as dynamic predicate methods.

http://github.com/jeffp/enumerated_attribute/tree/master

+3
Jul 15 '09 at 1:32
source share

Add the following:

 module ActiveRecord
   module ConnectionAdapters #: nodoc:
     class TableDefinition
       def enum (* args)
         options = args.extract_options!
         column_names = args

         column_names.each {| name |  column (name, 'enum', options)}
       end
     end
   end
 end

in lib / enum / table_definition.rb and include it in your init.rb.

+2
Mar 29 '09 at 10:28
source share

ok, just read all the rails api and find what I did and I don't like it :( Rails does not support emum as a native type during migration, here is the information, I need to find a plugin or other method.

I'll keep you up to date.

0
Mar 29 '09 at 22:28
source share

Another option: go to SQL.

 def self.up execute "ALTER TABLE `payments` ADD `status` ENUM('accepted', 'cancelled', 'pending')" end 
0
Mar 31 '09 at 18:34
source share

Using simple_form, I use this:

 <%= f.input :gender, :collection => {'Male' => 'male','Female' => 'female'}, :include_blank => false %> 
0
Feb 24 '12 at 23:26
source share



All Articles