使用 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:46:24  来源:igfitidea点击:

What is the best way to handle constants in Ruby when using Rails?

ruby-on-railsrubyconstantsenumeration

提问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