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

huacnlee for Rails Engine Gem · 2019年06月24日 · 最后由 ruby_sky 回复于 2019年06月25日 · 1991 次阅读

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

比如:

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

然而我们在使用的时候会发现,往往我们需要将 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

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

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


使用方法

gem "enumize"

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

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

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

现在你有了 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"

config/locales/zh-CN.yml

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

下面是使用的演示:

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"

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

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

项目地址

https://github.com/huacnlee/enumize

共收到 6 条回复

很实用,以前都是手动调用 i18n 👍

xeruzo 回复

关键是和 Rails 标准方式集成

有点重复造轮子.

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册