DEV Community

Jason Lee
Jason Lee

Posted on • Originally published at ruby-china.org on

Enumize - 扩展 ActiveRecord::Enum 增加实用方法

Rails 4.2 (如果没记错)给我们带来了官方的 Enum 解决方案,目前大家都在使用它了。

比如:

class Book
  enum status: %i[draft published archived]
end

Enter fullscreen mode Exit fullscreen mode

然而我们在使用的时候会发现,往往我们需要将 status 字段用中文或其他的方式在界面上显示,而不是一个 draft / published / archived

于是很多人可能会这样:

class Book
  enum status: %i[draft published archived]

  def status_name
    case status
    when "draft" then "草稿"
    when "published" then "已发布"
    when "archived" then "归档"
    end
  end
end

Enter fullscreen mode Exit fullscreen mode

然后随着项目的推进,你会发现你的 Model 里面大量有这种函数。

为了解决这个问题,我们最初在自己的项目里面实现了一个扩展,用于代替 enum 的定义,给它增加一些函数扩展,现在提取成一个 Gem,可以方便以后使用。


使用方法

gem "enumize"

Enter fullscreen mode Exit fullscreen mode

然后你的原来的 enum 定义不需要改变,这个 Gem 已经覆盖了那个方法。

🚨 所以,你可以认为这个 Gem 的引入不会改变 ActiveRecord::Enum 的原有使用方式,你可以无缝的集成到你的项目中!

class Book
  enum status: %i[draft published archived]
end

Enter fullscreen mode Exit fullscreen mode

现在你有了 status_name, status_color, status_value 以及 Book.status_options 这些方法:

  • #{attribute}_name - 返回 name 的 I18n 信息,用于显示
  • #{attribute}_color - 返回从 I18n 里面读取 color 的信息(如果你项目用不到可以忽略它)
  • #{attribute}_value - 返回原始的数据库值,用来代替 Book.statuses[@book.status]
  • Book.#{attribute}_options - 返回一个 Array,用于 select tag,比如 <%= f.select :status, Book.status_options %>.

配置 I18n:

config/locales/en.yml

en:
  activerecord:
    enums:
      book:
        status:
          draft: Drafting
          published: Published
          archived: Archived
        status_color:
          draft: "#999999"
          published: "green"
          archived: "red"

Enter fullscreen mode Exit fullscreen mode

config/locales/zh-CN.yml

zh-CN:
  activerecord:
    enums:
      book:
        status:
          draft: "草稿"
          published: "已发布"
          archived: "归档"

Enter fullscreen mode Exit fullscreen mode

下面是使用的演示:

irb> @book = Book.new(status: :draft)
irb> @book.status
"draft"
irb> @book.draft?
true
irb> @book.published?
false
irb> @book.status_value
0
irb> @book.status_name
"草稿"
irb> @book.status_color
"#999999"

Enter fullscreen mode Exit fullscreen mode

status_options 方法用在 View 里面的演示:

<% form_for(@book) do |f| %>
  <%= f.text_field :name %>
  <%= f.select :status, Book.status_options %>
  <%= f.submit %>
<% end >

Enter fullscreen mode Exit fullscreen mode

项目地址

https://github.com/huacnlee/enumize

Top comments (0)