web-dev-qa-db-fra.com

Quelle est la meilleure façon de gérer les constantes dans Ruby lorsque vous utilisez Rails?

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?

43
Miles

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']
40
Codebeef

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
11
Micah

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.

9
Dave

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.

7
Simone Carletti

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

5
Dema

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
0
Ady Rosen