【问题标题】:ActiveRecord::Enum initialized with hash or array?ActiveRecord::Enum 用散列或数组初始化?
【发布时间】:2022-11-20 15:41:03
【问题描述】:

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

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}

我很难知道什么时候将枚举声明为哈希或仅具有模型和枚举名称的数组。

关于如何从枚举中获取初始哈希或数组的任何想法?

【问题讨论】:

  • 为什么你需要知道?您试图通过确定枚举的定义方式来解决什么问题?你想区别对待enum status: %i[draft published archived]enum status: { draft: 0, published: 1, archived: 2 }吗?
  • @muistooshort 是的,我正在为 Avo (avohq.io) 开发一项功能,我需要稍微区别对待它们
  • 如果无法解决这个问题,我们需要让开发人员指定枚举的类型,我们正在努力避免这种情况
  • 我不认为你可以,source 只是检查它如何迭代值(each_pair 如果它是哈希,each_with_index 否则)。
  • 我想知道我们是否可以通过某种方式获得 source 收到的 values 参数

标签: ruby-on-rails activerecord enums


【解决方案1】:

由于最小意外原则,您不应该区别对待它们。

enum status: [:draft, :published, :archived] 只是定义枚举的隐式简写,其中映射与数组的索引相同。它也被认为是一种不好的做法,因为在数组中间添加新状态会以一种非常偷偷摸摸的方式破坏你的应用程序,甚至有一个 Rubocop 警察通过在源代码上使用正则表达式来检测。

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

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

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

module WonkyEnum
  def enum(definitions)
    @_enum_definitions ||= []
    @_enum_definitions.push(definitions)
    super(definitions)
  end
end

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2016-03-08
    • 1970-01-01
    • 2013-07-06
    • 2019-08-15
    • 2014-10-09
    • 2023-03-13
    相关资源
    最近更新 更多