2008-11-05 3 views
42

У меня есть некоторые константы, которые представляют действительные параметры в одном из полей моей модели. Каков наилучший способ обработки этих констант в Ruby?Каков наилучший способ обработки констант в Ruby при использовании Rails?

+0

[Это другой вопрос о Перечисления в Ruby, кажется, очень очень похоже] (http://stackoverflow.com/questions/164714/how-can-i-use-c-style-enumerations-in-ruby) – 2008-11-05 20:46:37

ответ

38

Вы можете использовать массив или хеш для этой цели (в вашей среде.rb):

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

или, альтернативно, перечисление c деваха, которая позволяет перечислить через свои константы, а также ключи, используемые для ассоциирования их:

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 

, которые затем можно извлечь из:

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

и использовать так:

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

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

Я решил пойти с этим решением. Должен сказать, он делает то, что я хочу, и отлично играет с ActiveRecord. Спасибо!: D – Miles 2008-11-06 21:45:54

11

я их прямо в классе модели, например, так:

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

Затем, при использовании модели из другого класса, я ссылаться на константы

@model.status = MyClass::ACTIVE_STATUS 
@model.save 
+2

Это метод, а не класс. Необходимо использовать «класс» вместо «def». – weexpectedTHIS 2012-03-23 16:53:49

5

Вы также можете использовать его в своей модели внутри хеша:


class MyModel 

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

И использовать его как это:



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

+0

Спасибо за это. Это было вдохновение для группировки символов в массиве. – chipairon 2013-04-09 08:07:40

9

Если гонит модель поведения, то константы должны быть частью модели:

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

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

Это позволит использовать встроенный Рельсы функциональность:

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

в качестве альтернативы, если ваша база данных поддерживает перечисления, то вы можете использовать что-то вроде Enum Column плагина ,

6

Rails 4.1 добавлено support for ActiveRecord enums.

Объявить атрибут enum, где значения соответствуют целым числам в базе данных, но могут быть запрошены по имени.

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

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

Conversation.archived # => Relation for all archived Conversations 

См its documentation для детального подправить.

+0

Я думаю, что это лучший ответ. – 2015-09-16 19:42:28

0

Можно также группировать константы в субъектах, используя модуль -

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

А затем,

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