Ruby on rails 如何处理rails枚举?

Ruby on rails 如何处理rails枚举?,ruby-on-rails,enums,ruby-on-rails-4,Ruby On Rails,Enums,Ruby On Rails 4,如何在rails中处理枚举?我在谷歌上搜索过这个,但没有找到任何干净的解决方案。到目前为止,我已经提出了以下关于使用交互类型id的模型的关注点。这是我在数据库中枚举表的外键。使用这种方法,我不必在所有代码中都使用ID,但在保存与interact_类型相关的对象时,我可以说 myobject.interaction_type = :file_download 这样就可以使用正确的id将问题持久化到数据库中,因为问题(请参阅下面的问题-包括在使用枚举的模型上)将返回正确的id module Int

如何在rails中处理枚举?我在谷歌上搜索过这个,但没有找到任何干净的解决方案。到目前为止,我已经提出了以下关于使用交互类型id的模型的关注点。这是我在数据库中枚举表的外键。使用这种方法,我不必在所有代码中都使用ID,但在保存与interact_类型相关的对象时,我可以说

myobject.interaction_type = :file_download
这样就可以使用正确的id将问题持久化到数据库中,因为问题(请参阅下面的问题-包括在使用枚举的模型上)将返回正确的id

module InteractionTypeEnum
  extend ActiveSupport::Concern

  included do
    INTERACTION_TYPE = { file_download: 1, email: 2, telesales: 3, registration: 4, enrolment: 5 }
  end

  def interaction_type
    INTERACTION_TYPE.key(read_attribute(:interaction_type_id)).to_s.gsub('_',' ').capitalize
  end

  def interaction_type=(s)
    write_attribute(:interaction_type_id, INTERACTION_TYPE[s])
  end
end    
这感觉很重。一定有更简单/更干净的方法。现在,当试图为此编写测试时,它变得更加混乱

在代码和数据库中需要枚举的大多数原因是性能(代码)和报告(数据库)


谢谢你的帮助。谢谢。

我使用以下方法,假设我有

class PersonInfo < ActiveRecord::Base
  belongs_to :person_info_type
end
我有一个种子,用相应的数据填充数据库

因此,当分配给某些人信息时,可以执行如下操作

person.person_infos << PersonInfo.create(:info => 'http://www.some-url.com', :person_info_type_id => PersonInfoType::URL)
person.person\u infos'http://www.some-url.com“,:person\u info\u type\u id=>personinfo::URL)
然后可以使用关系进一步清理此代码:

class PersonInfo

  belongs_to :person_info_type

  def self.phones
    PersonInfo.where(:person_info_type_id => PersonInfoType::PHONE)
  end

end

person.person_infos << PersonInfo.phones.create(:info => '555 12345')
类PersonInfo
属于:个人信息类型
def自助电话
PersonInfo.where(:person\u info\u type\u id=>PersonInfo::PHONE)
结束
结束
person.person_信息'555 12345')
我推荐gem

例如,如果在类
User
上有一个名为
sex
的整数列,则:

class User < ActiveRecord::Base
  enumerate :sex do
    value :name => 'Male'
    value :name => 'Female'
  end
end
class用户“男性”
值:name=>“女性”
结束
结束
也可以在单独的类中定义枚举:

class Sex < ActiveEnum::Base
  value 1 => 'Male'
  value 2 => 'Female'
end

class User < ActiveRecord::Base
  enumerate :sex, :with => Sex
end
class Sex“男性”
值2=>“女性”
结束
类用户sex
结束

我喜欢它提供的抽象,它使您不必仅为了存储枚举值而创建整个数据库表。

这是一个不错的解决方案,但假设您现在将用户存储在数据库中,并且希望通过后端访问用户的性别。你是说这应该作为字符串存储在数据库中-男性,女性。如果您的枚举集增加到10个项目,并且此后不会更改,会发生什么情况。您不希望数据库中的表中包含此信息吗?在某些情况下,您可能还希望扩展枚举以包含其他信息,如排名/顺序或描述。我知道这是多么有用和干净,但它可能有点有限。它作为一个整数存储在数据库中,并且有比我在这里复制粘贴的功能多得多的功能(例如,你可以向你描述的枚举添加扩展信息)。我建议尝试一下,如果只是想了解更多信息,看看它是否适合你的目的;我在多个项目中使用过它,从来没有遇到过问题。但当然,这不是唯一的解决方案(我相信还有其他enum Gem,或者你可以像其他答案一样推出自己的enum Gem),而且我没有在这方面投入太多资金,其他建议也会奏效。我已经查看了github。看起来非常好,但它似乎不支持rails 4。当我在代码中启用config.extend_classes=[ActiveRecord::Base]并尝试运行rails控制台时,我得到/Users/ryanme/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/activerecord-4.0.2/lib/active\u record/dynamic\u matchers.rb:22:in
method\u missing:activerecord的未定义方法(命名者)------据我所知,class_inheritable_accessor已被弃用。我看到rails 4.1.0.beta1内置了枚举。这可能是一个好办法。哦,是的,Rubygems上的版本与rails 4不兼容,这让我很困惑。尝试将
gem'active_enum',github'adzap/active_enum'
添加到您的Gemfile中,这对我很有效。该死,我听起来像是这颗宝石的传道者,真的,我对这两种方式都不太关心,这只是我费心去了解的唯一解决方案!我不知道Enum将出现在4.1.0中,这听起来是一个很好的改进。
class Sex < ActiveEnum::Base
  value 1 => 'Male'
  value 2 => 'Female'
end

class User < ActiveRecord::Base
  enumerate :sex, :with => Sex
end