I would like to create an enum field at sone migration I\'m doing, I tried searching in google but I can\'t find the way to do it in the migration
the only thing I f
I have dozens of these little enums, with 3-300 entries in each. I implement them as lookup tables. I don't have a model file for each one; I use some metaprogramming to generate a model for each, since each table has the same set of columns (id, name, description).
Since some of the sets had enough elements to warrant their own table, it was more consistent to move them all to tables. Just another option if you'll have more of these enums later.
EDIT: Here's how I generate 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 lives in the models directory, and is included in application_config.rb
. This lets me do stuff like this:
AccountState.ids
# => {"active" => 1, "deleted" => 2}
AccountState.values
# => {1 => "Active", 2 => "Deleted"}
AccountState.id_for("Active")
# => 1
AccountState.value_for(1)
# => "active"
Another option: drop to SQL.
def self.up
execute "ALTER TABLE `payments` ADD `status` ENUM('accepted', 'cancelled', 'pending')"
end
With simple_form i use this:
<%= f.input :gender, :collection => {'Male' => 'male','Female' => 'female'}, :include_blank => false %>
You can try the (very) comprehensive jeff's 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 fine for me! =D
Have you looked at the enum-column plugin on RubyForge?
Look at tip #3 on http://zargony.com/2008/04/28/five-tips-for-developing-rails-applications
This 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
HTH