使用 Rails 时在 Ruby 中处理常量的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/265725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to handle constants in Ruby when using Rails?
提问by Miles
I have some constants that represent the valid options in one of my model's fields. What's the best way to handle these constants in Ruby?
我有一些常量代表我的模型字段之一中的有效选项。在 Ruby 中处理这些常量的最佳方法是什么?
采纳答案by Codebeef
You can use an array or hash for this purpose (in your environment.rb):
为此,您可以使用数组或散列(在您的 environment.rb 中):
OPTIONS = ['one', 'two', 'three']
OPTIONS = {:one => 1, :two => 2, :three => 3}
or alternatively an enumeration class, which allows you to enumerate over your constants as well as the keys used to associate them:
或者枚举类,它允许您枚举常量以及用于关联它们的键:
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
which you can then derive from:
然后您可以从中得出:
class Values < Enumeration
self.add_item(:RED, '#f00')
self.add_item(:GREEN, '#0f0')
self.add_item(:BLUE, '#00f')
end
and use like this:
并像这样使用:
Values::RED => '#f00'
Values::GREEN => '#0f0'
Values::BLUE => '#00f'
Values.keys => [:RED, :GREEN, :BLUE]
Values.values => ['#f00', '#0f0', '#00f']
回答by Micah
I put them directly in the model class, like so:
我将它们直接放在模型类中,如下所示:
class MyClass < ActiveRecord::Base
ACTIVE_STATUS = "active"
INACTIVE_STATUS = "inactive"
PENDING_STATUS = "pending"
end
Then, when using the model from another class, I reference the constants
然后,当使用另一个类的模型时,我引用了常量
@model.status = MyClass::ACTIVE_STATUS
@model.save
回答by Dave
If it is driving model behavior, then the constants should be part of the model:
如果是驱动模型行为,那么常量应该是模型的一部分:
class Model < ActiveRecord::Base
ONE = 1
TWO = 2
validates_inclusion_of :value, :in => [ONE, TWO]
end
This will allow you to use the built-in Rails functionality:
这将允许您使用内置的 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
Alternatively, if your database supports enumerations, then you can use something like the Enum Columnplugin.
或者,如果您的数据库支持枚举,那么您可以使用Enum Column插件之类的东西。
回答by Simone Carletti
Rails 4.1 added support for ActiveRecord enums.
Rails 4.1 添加了对 ActiveRecord 枚举的支持。
Declare an enum attribute where the values map to integers in the database, but can be queried by name.
声明一个枚举属性,其中值映射到数据库中的整数,但可以按名称查询。
class Conversation < ActiveRecord::Base
enum status: [ :active, :archived ]
end
conversation.archived!
conversation.active? # => false
conversation.status # => "archived"
Conversation.archived # => Relation for all archived Conversations
See its documentationfor a detailed write up.
回答by Dema
You can also use it within your model inside a hash like this:
你也可以在你的模型中使用它,像这样:
class MyModel
SOME_ATTR_OPTIONS = {
:first_option => 1,
:second_option => 2,
:third_option => 3
}
end
And use it like this:
并像这样使用它:
if x == MyModel::SOME_ATTR_OPTIONS[:first_option]
do this
end
回答by Ady Rosen
You can also group constants into subjects, using a module --
您还可以使用模块将常量分组到主题中——
class Runner < ApplicationRecord
module RUN_TYPES
SYNC = 0
ASYNC = 1
end
end
And then have,
然后有,
> Runner::RUN_TYPES::SYNC
=> 0
> Runner::RUN_TYPES::ASYNC
=> 1

