it-swarm.com.de

Was ist der beste Weg, um mit Konstanten in Ruby umzugehen, wenn Sie Rails verwenden?

Ich habe einige Konstanten, die die gültigen Optionen in einem der Felder meines Modells darstellen. Was ist der beste Weg, um mit diesen Konstanten in Ruby umzugehen?

43
Miles

Sie können zu diesem Zweck ein Array oder einen Hash (in Ihrer environment.rb) verwenden:

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

oder alternativ eine Aufzählungsklasse, mit der Sie über Ihre Konstanten sowie die dazugehörigen Schlüssel auflisten können:

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

von denen Sie dann ableiten können:

class Values < Enumeration
  self.add_item(:RED, '#f00')
  self.add_item(:GREEN, '#0f0')
  self.add_item(:BLUE, '#00f')
end

und wie folgt verwenden:

Values::RED    => '#f00'
Values::GREEN  => '#0f0'
Values::BLUE   => '#00f'

Values.keys    => [:RED, :GREEN, :BLUE]
Values.values  => ['#f00', '#0f0', '#00f']
40
Codebeef

Ich stelle sie direkt in die Modellklasse, so:

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

Wenn ich dann das Modell aus einer anderen Klasse verwende, beziehe ich mich auf die Konstanten

@model.status = MyClass::ACTIVE_STATUS
@model.save
11
Micah

Wenn es das Verhalten von Modellen steuert, sollten die Konstanten Teil des Modells sein:

class Model < ActiveRecord::Base
  ONE = 1
  TWO = 2

  validates_inclusion_of :value, :in => [ONE, TWO]
end

Auf diese Weise können Sie die integrierte Rails-Funktion verwenden:

>> m=Model.new
=> #<Model id: nil, value: nil, created_at: nil, updated_at: nil>
>> m.valid?
=> false
>> m.value = 1
=> 1
>> m.valid?
=> true

Wenn Ihre Datenbank Enumerationen unterstützt, können Sie alternativ etwas wie das Enum Column plugin verwenden.

9
Dave

Rails 4.1 hinzugefügt Unterstützung für ActiveRecord-Enums .

Deklarieren Sie ein Aufzählungsattribut, bei dem die Werte in der Datenbank ganzen Zahlen zugeordnet werden, die jedoch nach Name abgefragt werden können.

class Conversation < ActiveRecord::Base
  enum status: [ :active, :archived ]
end

conversation.archived!
conversation.active? # => false
conversation.status  # => "archived"

Conversation.archived # => Relation for all archived Conversations

Siehe seine Dokumentation für eine ausführliche Beschreibung.

7
Simone Carletti

Sie können es auch innerhalb Ihres Modells in einem Hash wie folgt verwenden:


class MyModel

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

Und benutze es so:



if x == MyModel::SOME_ATTR_OPTIONS[:first_option]
  do this
end

5
Dema

Sie können Konstanten auch mit einem Modul in Subjekten gruppieren. 

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

Und dann haben

> Runner::RUN_TYPES::SYNC
 => 0
> Runner::RUN_TYPES::ASYNC
 => 1
0
Ady Rosen