J'ai des constantes qui représentent les options valides dans l'un des champs de mon modèle. Quelle est la meilleure façon de gérer ces constantes dans Ruby?
Vous pouvez utiliser un tableau ou un hachage à cette fin (dans votre environnement.rb):
OPTIONS = ['one', 'two', 'three']
OPTIONS = {:one => 1, :two => 2, :three => 3}
ou bien une classe d'énumération, qui vous permet d'énumérer vos constantes ainsi que les clés utilisées pour les associer:
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
dont vous pouvez alors tirer:
class Values < Enumeration
self.add_item(:RED, '#f00')
self.add_item(:GREEN, '#0f0')
self.add_item(:BLUE, '#00f')
end
et utiliser comme ceci:
Values::RED => '#f00'
Values::GREEN => '#0f0'
Values::BLUE => '#00f'
Values.keys => [:RED, :GREEN, :BLUE]
Values.values => ['#f00', '#0f0', '#00f']
Je les mets directement dans la classe de modèle, comme suit:
class MyClass < ActiveRecord::Base
ACTIVE_STATUS = "active"
INACTIVE_STATUS = "inactive"
PENDING_STATUS = "pending"
end
Ensuite, lors de l'utilisation du modèle d'une autre classe, je référence les constantes
@model.status = MyClass::ACTIVE_STATUS
@model.save
S'il s'agit du comportement du modèle, les constantes doivent en faire partie:
class Model < ActiveRecord::Base
ONE = 1
TWO = 2
validates_inclusion_of :value, :in => [ONE, TWO]
end
Cela vous permettra d'utiliser la fonctionnalité intégrée 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
Si votre base de données prend en charge les énumérations, vous pouvez également utiliser quelque chose comme: Enum Column plugin.
Rails 4.1 ajouté prise en charge des énumérations ActiveRecord .
Déclarez un attribut enum où les valeurs sont mappées sur des entiers dans la base de données, mais peuvent être interrogées par nom.
class Conversation < ActiveRecord::Base
enum status: [ :active, :archived ]
end
conversation.archived!
conversation.active? # => false
conversation.status # => "archived"
Conversation.archived # => Relation for all archived Conversations
Voir sa documentation pour une rédaction détaillée.
Vous pouvez également l'utiliser dans votre modèle dans un hachage comme celui-ci:
class MyModel
SOME_ATTR_OPTIONS = {
:first_option => 1,
:second_option => 2,
:third_option => 3
}
end
Et utilisez-le comme ceci:
if x == MyModel::SOME_ATTR_OPTIONS[:first_option]
do this
end
Vous pouvez également regrouper des constantes en sujets, à l'aide d'un module -
class Runner < ApplicationRecord
module RUN_TYPES
SYNC = 0
ASYNC = 1
end
end
Et puis,
> Runner::RUN_TYPES::SYNC
=> 0
> Runner::RUN_TYPES::ASYNC
=> 1