¿Cuál es la mejor manera de manejar constantes en Ruby cuando se usan Rails?
-
06-07-2019 - |
Pregunta
Tengo algunas constantes que representan las opciones válidas en uno de los campos de mi modelo. ¿Cuál es la mejor manera de manejar estas constantes en Ruby?
Solución
Puede usar una matriz o hash para este propósito (en su ambiente.rb):
OPTIONS = ['one', 'two', 'three']
OPTIONS = {:one => 1, :two => 2, :three => 3}
o, alternativamente, una clase de enumeración, que le permite enumerar sus constantes, así como las claves utilizadas para asociarlas:
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
que puede derivar de:
class Values < Enumeration
self.add_item(:RED, '#f00')
self.add_item(:GREEN, '#0f0')
self.add_item(:BLUE, '#00f')
end
y úsalo así:
Values::RED => '#f00'
Values::GREEN => '#0f0'
Values::BLUE => '#00f'
Values.keys => [:RED, :GREEN, :BLUE]
Values.values => ['#f00', '#0f0', '#00f']
Otros consejos
Los puse directamente en la clase de modelo, así:
class MyClass < ActiveRecord::Base
ACTIVE_STATUS = "active"
INACTIVE_STATUS = "inactive"
PENDING_STATUS = "pending"
end
Luego, cuando uso el modelo de otra clase, hago referencia a las constantes
@model.status = MyClass::ACTIVE_STATUS
@model.save
Si está conduciendo el comportamiento del modelo, entonces las constantes deberían ser parte del modelo:
class Model < ActiveRecord::Base
ONE = 1
TWO = 2
validates_inclusion_of :value, :in => [ONE, TWO]
end
Esto le permitirá utilizar la funcionalidad integrada de Rails:
>> m=Model.new
=> #<Model id: nil, value: nil, created_at: nil, updated_at: nil>
>> m.valid?
=> false
>> m.value = 1
=> 1
>> m.valid?
=> true
Alternativamente, si su base de datos admite enumeraciones, puede usar algo como Complemento Columna de enumeración .
Rails 4.1 agregó soporte para enumeraciones ActiveRecord .
Declara un atributo enum donde los valores se asignan a enteros en la base de datos, pero se pueden consultar por nombre.
class Conversation < ActiveRecord::Base
enum status: [ :active, :archived ]
end
conversation.archived!
conversation.active? # => false
conversation.status # => "archived"
Conversation.archived # => Relation for all archived Conversations
Consulte su documentación para obtener una descripción detallada.
También puede usarlo dentro de su modelo dentro de un hash como este:
class MyModel
SOME_ATTR_OPTIONS = {
:first_option => 1,
:second_option => 2,
:third_option => 3
}
end
Y úsalo así:
if x == MyModel::SOME_ATTR_OPTIONS[:first_option]
do this
end
También puede agrupar constantes en temas, usando un módulo -
class Runner < ApplicationRecord
module RUN_TYPES
SYNC = 0
ASYNC = 1
end
end
Y luego tener,
> Runner::RUN_TYPES::SYNC
=> 0
> Runner::RUN_TYPES::ASYNC
=> 1