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
- Fork it ( https://github.com/brianclio/rails_column_enumerator/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request