将枚举值映射到字符串类型而不是整数的可能性

枚举属性很棒,我想使用它们。 但是将枚举值映射到整数将使得难以维护代码和数据库。 此外,我的数据库将与我的代码高度耦合,我认为我应该认为这是一件坏事。

我知道我可以使用哈希来组织具有键/值对的枚举属性,但是能够使用数组并映射到数据库中的字符串值仍然会好得多。

有默认情况下将枚举映射到字符串的方法吗?

据我所知,使用Active Record的内置枚举function是不可能的。 但是,有一些流行的第三方gem可以做到这一点。 与Active Record最接近的匹配可能是枚举和SimpleEnum 。

但是,如果你正在寻找一些不同的东西,我会推荐ClassyEnum (完全披露:我写了它)。 以下是关于enumerize和SimpleEnum与ClassyEnum之间区别的一些注释 :

无类别枚举(enumerize,SimpleEnum)非常适用于简单的用例,您只需要一个字段来表示一组固定的值。 我对此解决方案的主要问题是它鼓励分散在整个模型,控制器和视图中的条件。 使用这些gem是很诱人的,因为它们是最简单的实现,但长期的收益并不是IMO,除了最简单的情况。

ClassyEnum旨在解决与不同枚举相关的分散条件逻辑的问题。 您仍然可以将它用于没有逻辑的简单集合,但是当您确实需要添加逻辑(并且几乎肯定会)时,您可以将其推送到单个枚举类中并利用多态性。

查看enum的代码,你可以这样做(至少在4.1+中): https : //github.com/rails/rails/blob/master/activerecord/lib/active_record/enum.rb#L96-98哈希,例如:

class Foo enum name: { foo: 'myfoo', bar: 'mybar' } 

在访问时会出现意外结果,请参阅https://github.com/rails/rails/issues/16459

 foo_instance.foo! foo_instance.name => "foo" foo_instance[:name] => "myfoo" 

更新

此问题已在Rails 5中修复,请参阅https://github.com/rails/rails/commit/c51f9b61ce1e167f5f58f07441adcfa117694301 。 谢谢Yuri。

最简洁的答案是不。 如果你想做任何事情而不是存储整数,你将需要使用gem(例如magic-enum )。

在DHH自己的话中,对添加此function的pull请求的评论:

将枚举存储为文本效率非常低。 你将一遍又一遍地重复相同的文字。 我认为这是一种反模式。 如果他们想要使用它,人们最好转移到int。

似乎仅使用Rails 5 API,模型的枚举属性将作为整数保存在数据库 ,但将作为字符串在公共API中发布(使用ActiveModel :: Serializer)。

例如,

文章模型:

 class Article < ApplicationRecord enum status: [ :visible, :hidden ] end 

文章序列化器:

 class ArticleSerializer < ActiveModel::Serializer attributes :id, :status, :title, :body end 

将发布以下json:

 { "id": "1", "type": "articles", "attributes": { "status": "visible", "title": "Enums are passed as string in a json API render", "body": "Great!", } 

怎么样:

 class Foo < ApplicationRecord NAMES = [ :foo, :bar ] enum names: NAMES.zip(NAMES).to_h end