class Conversation < ActiveRecord::Base
  enum status: [ :active, :archived ]
end

also you can define like this

class Conversation < ActiveRecord::Base
  enum status: { active: 0, archived: 1 }
end
# conversation.update! status: 0
conversation.active!
conversation.active? # => true
conversation.status  # => "active"

# conversation.update! status: 1
conversation.archived!
conversation.archived? # => true
conversation.status    # => "archived"

# conversation.update! status: 1
conversation.status = "archived"

# conversation.update! status: nil
conversation.status = nil
conversation.status.nil? # => true
conversation.status      # => nil

Conversation.statuses # => { "active" => 0, "archived" => 1 }

Default Values for Enums

create_table :conversations do |t|
  t.column :status, :integer, default: 0, null: false
end

query

Conversation.active
Conversation.archived
Conversation.send(my_conversation.status)

Conversation.where.not(status: 0)
Conversation.where("status <> ?", Conversation.statuses[:archived])
Conversation.where.not(status: my_conversation.status)

not work

Conversation.where(status: my_conversation.status)
Conversation.where(status: :archived)
Conversation.where(status: "archived")

Pluck vs Map with Enums

statuses_with_map = Conversation.select(:status).where.not(status: nil).distinct.map(&:status)               ===>  ["active", "archived"]
statuses_with_pluck = Conversation.distinct.where.not(status: nil).pluck(:status)                            ===>  [0, 1]

Enum Source

conversation.status = "archived"
conversation.status = 1
# both of these work
puts conversation.status # prints "archived"

You can look at the Rails source code for ActiveRecord::Enum.

# def status=(value) self[:status] = statuses[value] end
define_method("#{name}=") { |value|
  if enum_values.has_key?(value) || value.blank?
    # set the db value to the integer value for the enum
    self[name] = enum_values[value]
  elsif enum_values.has_value?(value) # values contains the integer
    self[name] = value
  else
    # enum_values did not have the key or value passed
    raise ArgumentError, "'#{value}' is not a valid #{name}"
  end
}

References:

  • http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html
  • https://hackhands.com/ruby-on-enums-queries-and-rails-4-1/?utm_source=rubyweekly&utm_medium=email