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?

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top