What is the best way to handle constants in Ruby when using Rails?

I have some constants that represent valid parameters in one of my model fields. What is the best way to handle these constants in Ruby?

+42
ruby enumeration ruby-on-rails constants
Nov 05 '08 at 16:31
source share
6 answers

You can use an array or hash for this purpose (in your .rb environment):

OPTIONS = ['one', 'two', 'three'] OPTIONS = {:one => 1, :two => 2, :three => 3} 

or, alternatively, an enumeration class that allows you to list your constants, as well as the keys used to bind 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 

from which you can get:

 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'] 
+38
Nov 05 '08 at 16:41
source share

I put them directly in the model class, for example:

 class MyClass < ActiveRecord::Base ACTIVE_STATUS = "active" INACTIVE_STATUS = "inactive" PENDING_STATUS = "pending" end 

Then, using a model from another class, I refer to the constants

 @model.status = MyClass::ACTIVE_STATUS @model.save 
+11
Nov 05 '08 at 16:38
source share

If this is the behavior of a behavior model, 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 function:

 >> 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, you can use something like the Enum Column plugin.

+9
Nov 05 '08 at 21:22
source share

Rails 4.1 has added support for ActiveRecord enumerations .

Declare an enum attribute, where the values ​​correspond to integers in the database, but can be requested by name.

 class Conversation < ActiveRecord::Base enum status: [ :active, :archived ] end conversation.archived! conversation.active? # => false conversation.status # => "archived" Conversation.archived # => Relation for all archived Conversations 

See its documentation for more details.

+6
Jan 09 '14 at 14:51
source share

You can also use it inside your model inside a hash, for example:

 class MyModel SOME_ATTR_OPTIONS = { :first_option => 1, :second_option => 2, :third_option => 3 } end 

And use it as follows:

 if x == MyModel::SOME_ATTR_OPTIONS[:first_option] do this end 
+5
Nov 05 '08 at 17:42
source share

You can also group constants into objects using the module -

 class Runner < ApplicationRecord module RUN_TYPES SYNC = 0 ASYNC = 1 end end 

And then,

 > Runner::RUN_TYPES::SYNC => 0 > Runner::RUN_TYPES::ASYNC => 1 
0
Jan 28 '17 at 12:58 on
source share



All Articles