I have some constants that represent the valid options in one of my model's fields. What's the best way to handle these constants in Ruby?
+2
A:
I put them directly in the model class, like so:
def MyClass < ActiveRecord::Base
ACTIVE_STATUS = "active"
INACTIVE_STATUS = "inactive"
PENDING_STATUS = "pending"
end
Then, when using the model from another class, I reference the constants
@model.status = MyClass::ACTIVE_STATUS
@model.save
Micah
2008-11-05 16:38:45
+8
A:
You can use an array or hash for this purpose (in your environment.rb):
OPTIONS = ['one', 'two', 'three']
OPTIONS = {:one => 1, :two => 2, :three => 3}
or alternatively an emumeration class, which allows you to enumerate over your constants as well the keys used to associate them:
class Enumeration
def Enumeration.add_item(key,value)
@hash ||= {}
@hash[key]=value
end
def Enumeration.const_missing(key)
@hash[key]
end
def Enumeration.each
@hash.each {|key,value| yield(key,value)}
end
def Enumeration.values
@hash.values || []
end
def Enumeration.keys
@hash.keys || []
end
def Enumeration.[](key)
@hash[key]
end
end
which you can then derive from:
class Values < Enumeration
self.add_value(:RED, '#f00')
self.add_value(:GREEN, '#0f0')
self.add_value(:BLUE, '#00f')
end
and use like this:
Values::RED => '#f00'
Values::GREEN => '#0f0'
Values::BLUE => '#00f'
Values.keys => [:RED, :GREEN, :BLUE]
Values.values => ['#f00', '#0f0', '#00f']
Mr. Matt
2008-11-05 16:41:31
I decided to go with this solution. I have to say, it does just what I want and plays nicely with ActiveRecord. Thank you! :D
Miles
2008-11-06 21:45:54
+2
A:
You can also use it within your model inside a hash like this:
class MyModel
SOME_ATTR_OPTIONS = {
:first_option => 1,
:second_option => 2,
:third_option => 3
}
end
And use it like this:
if x == MyModel::SOME_ATTR_OPTIONS[:first_option]
do this
end
Dema
2008-11-05 17:42:13
+2
A:
If it is driving model behavior, then the constants should be part of the model:
class Model < ActiveRecord::Base
ONE = 1
TWO = 2
validates_inclusion_of :value, :in => [ONE, TWO]
end
This will allow you to use the built-in Rails functionality:
>> m=Model.new
=> #<Model id: nil, value: nil, created_at: nil, updated_at: nil>
>> m.valid?
=> false
>> m.value = 1
=> 1
>> m.valid?
=> true
Alternatively, if your database supports enumerations, then you can use something like the Enum Column plugin.
Dave
2008-11-05 21:22:07