The simplest Enum you will ever find for your ActiveRecord models

I have been using a really useful snippet for a while now.

While dropping it today into a project I realized just how powerful it is:

  1. it’s a drop-in and will work on any project
  2. it’s database agnostic
  3. it’s dead simple
  4. it’s not sensitive to enum changes
  5. and more and more

Just as an into, an enum is a way to have string represented as integers in your database.

Why?

Because integers are much faster to index and query (at least on mysql).

MySQL has an enum solution but ActiveRecord can’t really use it without some nasty hacking and it’s really messy when you want to add another param.

Enough Said, here’s the snippet

  STATUS = { pending: 0, active: 1, inactive: 2, deleted: 3 }

  def status
    STATUS.key(read_attribute(:status))
  end

  def status=(s)
    write_attribute(:status, STATUS[s])
  end
view raw account.rb This Gist brought to you by GitHub.

This gives you the ability to work with the Account model like so:

>> account = Account.first
  Account Load (0.2ms) SELECT `accounts`.* FROM `accounts` LIMIT 1
=> #<Account id: 4, name: "KensoDev", subdomain: "kensodev", user_id: 6, created_at: "2012-05-08 16:06:31", updated_at: "2012-05-08 16:29:11", logo_file_name: nil, logo_content_type: nil, logo_file_size: nil, logo_updated_at: nil, token: "5022N7VSAD", plan_id: 1, project_count: 1, contact_count: 1, quota_used: 0, notification_interval: nil, billing_token: "", status: 1>
>> account.status
=> :active
>> account.status = :pending
=> :pending
>> account.save
  SQL (0.1ms) BEGIN
  Account Load (0.3ms) SELECT `accounts`.`id` FROM `accounts` WHERE (`accounts`.`subdomain` = BINARY 'kensodev') AND (`accounts`.id <> 4) LIMIT 1
User Load (0.2ms) SELECT `users`.* FROM `users` WHERE (`users`.`id` = 6) LIMIT 1
Plan Load (0.2ms) SELECT `plans`.* FROM `plans` WHERE (`plans`.`id` = 1) LIMIT 1
User Load (0.3ms) SELECT `users`.`id` FROM `users` WHERE (LOWER(`users`.`email`) = LOWER('avi@kensodev.com')) AND (`users`.id <> 6) LIMIT 1
[paperclip] Saving attachments.
AREL (0.2ms) UPDATE `accounts` SET `status` = 0, `updated_at` = '2012-05-08 16:29:40' WHERE (`accounts`.`id` = 4)
[paperclip] Saving attachments.
SQL (1.5ms) COMMIT
=> true
>>

As you can see, it’s being persisted into the database as an integer, but you work with symbols/strings which is much nicer and cleaner.

Thank you for your interest!

We will contact you as soon as possible.

Send us a message

Oops, something went wrong
Please try again or contact us by email at info@tikalk.com