RailsColumnEnumerator

Simple Gem to easily store attributes as enumerated values in ActiveRecord using Rails

Installation

Add this line to your application's Gemfile:

gem 'rails_column_enumerator'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rails_column_enumerator

Usage

Add extend RailsColumnEnumerator to the top of whatever class you want to add an enumerated column to.

Then define the attribute with enumerated_column method.

example:

class TestClass < ActiveRecord::Base
  extend RailsColumnEnumerator

  enumerated_column :state, { open: 1, closed: 2, failed: 3 }, scopes: { not_failed: [1, 2], not_open: [:closed, :failed] }
end

# The following two consts would be added to your class (Their name is derived from the attribute name you pass into 'enumerated_column')
TestClass::STATES # { "open" => 1, "closed" => 2, "failed" => 3 }
TestClass::STATE_NAMES # { 1 => :open, 2 => :closed, 3 => :failed }

# You can define options for select helpers using the 'selections' option
enumerated_column :state, { open: 1, closed: 2, failed: 3 }, selections: { not_failed: [1, 2], not_open: [:closed, :failed] }
TestClass.not_failed # [["Open", 1], ["Closed", 2]]
TestClass.not_open # [["Closed", 2], ["Failed", 3]]

# You can also add i18n localizations for these select helper outputs. 
# The gem matches values in the helpers with i18n entries under .models.class_name.column_name.scope_name(or default).key

# You can use your enumerated attribute as follows
example = TestClass.new

example.state = :closed

# When accessing the attribute it will return the integer value by default, if you want to return the symbol then simply pass in a parameter of "true"
# This is to maintain support for XML serialization of the object (to_xml) amongst other things.
example.state # 2
example.state(true) # :closed

example.state = 3

example.state # 3
example.state(true) # :failed

# The enumerated column will also be validated so that it must include values present in your enumerator

example.state = :pending
example.state # nil

example.state = 4
example.state # 4

example.state.save! # raises "ActiveRecord::RecordInvalid, 'Validation failed: State is not included in the list'"

# You can check if an instance of your class has its enumerated column set to a specific value.
example.state = 2

example.open?   # false
example.closed? # true

# You can add scopes on your enumerated column by passing in the scope name and an array containing values that should be included in your scope.

TestClass.not_failed # SELECT `test_class`.* FROM `test_class` WHERE `state` IN (1, 2);
TestClass.not_open # SELECT `test_class`.* FROM `test_class` WHERE `state` IN (2, 3);

# Values can be added to scopes as either their integer value or their key.
# If the values you enter are not valid values for your enumerator, or if you don't provide any, it will raise an error.

enumerated_column :state, { open: 1, closed: 2, failed: 3 }, scopes: { not_open: [1, 2, 5], finished: [:closed, :failed, :pending] } # Raises RuntimeError "Values in options must be valid for enumerated column."
enumerated_column :state, { open: 1, closed: 2, failed: 3 }, scopes: { not_open: [] } # Raises RuntimeError "You must provide some values for the scope."

# When you create a scope you also get an 'include?' method using that scope's name that allows you to check if a value is part of that scope.

example.not_failed_include?(1)       #true
example.not_failed_include?(:open)   #true

example.not_failed_include?(3)       #false
example.not_failed_include?(:failed) #false

Development

After checking out the repo, run bin/setup to install dependencies. Then, run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release to create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

  1. Fork it ( https://github.com/brianclio/rails_column_enumerator/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request