enum是rails的ActiveRecord中提供的一个枚举方法,它用来声明一些映射到整形数据的一些属性。

增加enum类型字段:

create_table :posts do |t|
  t.column :status, :integer, default: 0
end
  • 声明方式有array和hash两种
class Post < ActiveRecord::Base
  enum status: [ :inactive, :active ]
  # or
  enum status: { inactive: 0, active: 1 }
end

上述代码中两个映射是一致的,inactive映射0, active映射1。array写法比较简洁,默认映射数字是数组中元素的索引。hash写法更灵活,hash的值可以根据需求定义,不是必须连续的。为了代码的可维护性和灵活性,建议使用hash的写法。

  • 声明enum后,rails默认为我们提供了很多方法可供调用.

类方法,默认提供的Scope:

  Post.statuses       #=> {"inactive"=>0, "active"=>1}
  Post.inactive       #=> SELECT `posts`.* FROM `posts` WHERE `posts`.`status` = 0
  Post.active         #=> SELECT `posts`.* FROM `posts` WHERE `posts`.`status` = 1
  # Rails6版本中新增加了下面两个negative scope,注意你的enum值不可设置为not_开头。
  Post.not_active     # Post.where.not(status: :active)
  Post.not_inactive   # Post.where.not(status: :inactive)

当然也可以手动disable掉scope方法的生成

enum status: [ :inactive, :active ], _scopes: false

手动指定默认的enum值,new的时候默认status为active

enum status: [ :inactive, :active ], _default: "active"

实例方法:

  post = Post.last
  post.status     #=> active / inactive
  post.active?    #=> true / false
  post.inactive?  #=> true / false
  post.active!    #=> update post status to active
  post.inactive!  #=> update post status to inactive

查询语法:

  Post.where(status: [:active, :inactive])
  Post.where.not(status: :active)
  • 如果你想查找mapping对应的整形值,rails也提供了对应方法:
  Post.statuses[:active]    #=> 1
  Post.statuses[:inactive]  #=> 0
  # 比如你是通过拼接的sql来做查询,可以使用下面这样。
  Post.where("status <> ?", Post.statuses[:inactive])
  • 前/后缀写法

enum中提供了_prefix和_suffix参数,可以为enum的值增加前/后缀,当一些model中有很多enum字段时,方便对一些方法进行更加直观命名。

class Post < ActiveRecord::Base
  enum status: [:inactive, :active], _suffix: true
  enum publish_status: [:inactive, :active], _prefix: :publish
end
# 对应的方法则变为:
post.active_status?
Post.active_status
post.publish_active?
Post.publish_active