Skip to content

cmer/enumish

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Enumish

Enumish is "Database-backed Enum for ActiveRecord".

It gives you the ability to create Enum-like properties directly in the database.

Build Status

Simple Example

Given a model:

class Color < ActiveRecord
  include Enumish
end

You could do things such as:

color = Color.blue  # gets the color blue from the database
color.blue?         # => true
color.red?          # => false
color.to_s          # => "blue"
color.to_sym        # => :blue
color.id            # returns the ID from the database

Color.not_a_color  # raises MethodNotFound

A-bit-more-advanced-but-still-simple Example

You can combine Enumish with any other ActiveRecord functionality or Gems. For example, here's a model that uses Enumish and RankedModel, as well as some custom code.

class Color < ActiveRecord
  include RankedModel
  ranks :position
  include Enumish

  class << self
    def select_options
      Color.rank(:position).where(enabled: true).map do |s|
        { s.human_description => s.id }
      end
    end

    def all_primary
      Color.rank(:position).where(enabled: true).where(primary: true)
    end
  end

  def human_description
    "The color #{self.to_s}"
  end
end

Such a model allows you, for example, to have a relationship between two models such as:

class Car < ActiveRecord
  has_one :color
end

car = Car.new
car.color = Color.blue
car.save!

car.color.blue?          # => true
car.color.red?           # => false
car.color == Color.blue  # => true
car.color_id             # => Integer

# NOTE: table `cars` has column `color_id` of type `integer`

The method .select_options above could be used to populate an HTML select element. The value of each element would be the id of the corresponding Color record.

Migration

For each model that includes Enumish, add a column named short of type string. This column will be used to store the "short" representation of the record. It will also be used as a method name, so make sure it only contains characters that are valid in a Ruby method name.

class CreateColors < ActiveRecord::Migration[5.0]
  def change
    create_table :colors do |t|
      t.string :short, null: false   # << This!
      t.string :long, null: false
      t.boolean :enabled, default: true, null: false
      t.integer :position, null: false

      t.timestamps
    end
  end
end

If you'd rather name the column something else, you can override the enum_id method in your model:

class Color < ActiveRecord
  include Enumish

  def enum_id
    :enum_value
  end
end

Why not just use ActiveRecord::Enum?

Glad you asked! ActiveRecord::Enum (AR::E going forward) is an option you should definitely consider if it fits your needs. I wrote Enumish because I needed the following capabilities:

  • Ability to have more than one enum field per model.

    For example, a Car model could have the following Enumish properties: exterior_color, interior_color, model, transmission. This would not be possible with vanilla AR::E.

  • Database-backed properties. There are many benefits to this. Notably, Enumish allows you to:

    • Maintain an ever-evolving list of properties directly in the database instead of changing and potentially breaking code. Your marketing team will love this!
    • Keep a human-readable version of your Enumish properties in the database for your users to see, or for your eyes only. Just add a description column.
    • Enable or disable some properties. Just add an enabled column.
    • Sort how properties are displayed to end-users. Pro-tip, just use RankedModel.
    • Limit possible Enumish properties under different circumstances. For example, a car from 2015 might have different color options than a car from 2016. Or in the example above, I have an .all_primary method that only returns primary colors.
    • Perform database JOINs between your model and Enumish models.
    • Maintain data integrity between your models and Enumish models. It's all just SQL after all.

Installation

Add this line to your application's Gemfile:

gem 'enumish'

License

The gem is available as open source under the terms of the MIT License.

About

Database-backed Enum for ActiveRecord

Resources

License

Stars

Watchers

Forks

Packages

No packages published