ruby-on-rails ActiveRecord::枚举是用哈希还是数组初始化的?

s3fp2yjn  于 2022-11-26  发布在  Ruby
关注(0)|答案(1)|浏览(163)

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

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

当我们从模型(Project.stagesProject.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}

我很难知道什么时候枚举被声明为Hash还是只有model和枚举名的Array。
如何从枚举中获取初始哈希或数组?

hof1towb

hof1towb1#

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

enum status: [:draft, :published, :archived]只是定义一个枚举的隐式简写,其中的Map与数组的索引相同。这就是它的文档化方式,让你的代码做一些其他的事情会让你有一个真实的的WTF时刻。
隐式定义枚举也被认为是一种不好的做法,因为在数组中间添加新的状态会以一种非常隐蔽的方式破坏你的应用程序。甚至有一个Rubocop通过在源代码中使用正则表达式来检测数组的使用。
实际上,这只是一种草率的enum status: { draft: 0, published: 1, archived: 2}编写方式,您不应该鼓励使用它。
你传递给enum的参数只是用来对setter、getter进行元编程,并创建存储枚举Map的元数据。它不存储原始参数,因为没有指向原始参数的指针。
如果你真的想这样做,你可以monkeypatch枚举方法:

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

但无论真实的的问题是什么,都很可能有更好的解决方案。

相关问题