使用Rails时,在Ruby中处理常量的最佳方式是什么?

我有一些常量代表我的模型的字段中的有效选项。 在Ruby中处理这些常量的最好方法是什么?

你可以使用一个数组或哈希来达到这个目的(在你的environment.rb中):

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

或者一个枚举类,它允许你枚举你的常量以及用来关联它们的键:

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

我把它们直接放在模型类中,就像这样:

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

然后,当使用另一个类的模型时,我引用常量

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

如果是推动模型行为,那么常量应该是模型的一部分:

 class Model < ActiveRecord::Base ONE = 1 TWO = 2 validates_inclusion_of :value, :in => [ONE, TWO] end 

这将允许您使用内置的Railsfunction:

 >> 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插件的东西。

Rails 4.1增加了对ActiveRecord枚举的支持 。

声明一个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 

请参阅其文档以获得详细的信息。

你也可以在你的模型中使用它,如下所示:

 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 

您也可以使用模块将常量组合到主题中,

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

然后,

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