ActiveRecord::枚举初始化哈希或数组?



假设我们有一个简单的模型:

class Project < ApplicationRecord
enum stage: {Idea: "idea", Done: "done", "On hold": "on hold", Cancelled: "cancelled"}
enum status: [:draft, :published, :archived]
end

当我们从模型(Project.stages,Project.statuses)访问枚举时,我们得到的结果是处理(通过ActiveRecord::Enum)响应,两者都是哈希。

irb(main):001:0> Project.stages
=> {"Idea"=>"idea", "Done"=>"done", "On hold"=>"on hold", "Cancelled"=>"cancelled"}
irb(main):002:0> Project.statuses
=> {"draft"=>0, "published"=>1, "archived"=>2}

我正在努力知道enum何时被声明为哈希或仅具有模型和enum名称的数组。

关于如何从枚举中获得初始散列或数组的任何想法?

您不应该因为最小意外原则而区别对待它们。

enum status: [:draft, :published, :archived]只是定义一个枚举的隐式简写,其中映射与数组的下标相同。这就是它的文档,让你的代码做一些其他的事情,为真正的WTF时刻打开了大门。

隐式定义枚举也被认为是一种不好的做法,因为在数组中间添加新状态会以一种非常狡猾的方式破坏应用程序。甚至还有一个Rubocop cop,它通过在源代码上使用正则表达式来检测数组的使用。

这实际上只是enum status: { draft: 0, published: 1, archived: 2}的一种潦草的写法。你不应该鼓励它的使用。

传递给enum的参数只是用于对setter、getter进行元编程,并创建存储枚举映射的元数据。它不存储原始参数,因为没有指向。

如果你真的想这样做,你可以monkeypatch枚举方法:

module WonkyEnum
# this is silly. Don't do this
def enum(definitions)
@_enum_definitions ||= []
@_enum_definitions.push(definitions)
super(definitions)
end
end

但不管真正的问题是什么,很可能有一个更好的解决方案。