What is the best way to handle constants in Ruby when using Rails?
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 enumeration class, which allows you to enumerate over your constants as well as 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] endend
which you can then derive from:
class Values < Enumeration self.add_item(:RED, '#f00') self.add_item(:GREEN, '#0f0') self.add_item(: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']
I put them directly in the model class, like so:
class 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
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.