README.md in rails_attr_enum-0.1.0 vs README.md in rails_attr_enum-0.1.1
- old
+ new
@@ -1,170 +1,230 @@
# RailsAttrEnum
-## Enums for Rails models
-I created RailsAttrEnum as a way to create an enum-like structure similar to
-enums in C languages. You can specify the accepted identifiers for the possible
-integer values for the model's attribute as well have built-in validation to
-ensure only the values are accepted.
+Enums for Rails attributes. Specify enumeration identifiers for int attributes
+on your Rails models. Includes constants for your identifiers, validation,
+model class scopes, and instance helper methods.
-### Usage
+## Build Status
+[![Build Status](https://travis-ci.org/jfairbank/rails_attr_enum.png?branch=master)](https://travis-ci.org/jfairbank/rails_attr_enum)
-Here's an example given a class `User` with an attribute `role`:
+## Installation
+Add to your Gemfile:
- # Example model User for a blog app
- class User < ActiveRecord::Base
- extend RailsAttrEnum
+```ruby
+gem 'rails_attr_enum'
+```
- attr_enum :role, :admin, :editor, :author, :user
- end
+And then run bundler:
- # Creates module `User::Role` with constants for each possible value
- User::Role::ADMIN == 0
- User::Role::EDITOR == 1
- User::Role::AUTHOR == 2
- User::Role::USER == 3
+ $ bundle install
+## Usage
+
+Here's an example given a class `User` with an attribute `role`:
+
+```ruby
+# Example model User for a blog app
+class User < ActiveRecord::Base
+ extend RailsAttrEnum
+ attr_enum :role, :admin, :editor, :author, :user
+end
+
+# Creates module `User::Role` with constants for each possible value
+User::Role::ADMIN == 0
+User::Role::EDITOR == 1
+User::Role::AUTHOR == 2
+User::Role::USER == 3
+```
+
[View other ways to define and customize enums](https://github.com/jfairbank/rails_attr_enum/wiki/Adding-an-Enum-to-a-Model)
-### Helpers for Model Instances
+## Helpers for Model Instances
A couple helpers methods are added to the model and the enum attribute.
Get the "display" label for the current value with the `display_*` method:
- user = User.new(User::Role::ADMIN)
- user.display_role == 'Admin'
+```ruby
+user = User.new(role: User::Role::ADMIN)
+user.display_role == 'Admin'
+```
You can check for a specific value with a query `*?` method:
- user = User.new(User::Role::AUTHOR)
- user.role.admin? # false
- user.role.editor? # false
- user.role.author? # true
- user.role.user? # false
+```ruby
+user = User.new(role: User::Role::AUTHOR)
+user.role.admin? # false
+user.role.editor? # false
+user.role.author? # true
+user.role.user? # false
+```
The query method works via a forwarding class, so the normal `role` and `role=`
methods should work as expected.
**NOTE**: one caveat to this is if you try to use
a hash map of the enum values to some other value. See below:
- alt_label_map = {
- User::Role::ADMIN => 'The admin user',
- User::Role::EDITOR => 'An editor',
- User::Role::AUTHOR => 'An author',
- User::Role::USER => 'A user'
- }
+```ruby
+alt_label_map = {
+ User::Role::ADMIN => 'The admin user',
+ User::Role::EDITOR => 'An editor',
+ User::Role::AUTHOR => 'An author',
+ User::Role::USER => 'A user'
+}
- user = User.new(User::Role::EDITOR)
- alt_label = alt_label_map[user.role]
- alt_label == nil # not 'An editor'
+user = User.new(role: User::Role::EDITOR)
+alt_label = alt_label_map[user.role]
+alt_label == nil # not 'An editor'
+```
-If you want the hash to work as expected than call the `.value` method on the
+If you want the hash to work as expected then call the `.value` method on the
attribute:
- alt_label = alt_label_map[user.role.value]
- alt_label == 'An editor'
+```ruby
+alt_label = alt_label_map[user.role.value]
+alt_label == 'An editor'
+```
Thus, the `.value` method on the attribute gives the actual `Fixnum` value.
There is also a `.key` method which gives the symbol key:
- user = User.new(User::Role::ADMIN)
- user.role.key == :admin
+```ruby
+user = User.new(role: User::Role::ADMIN)
+user.role.key == :admin
+```
The attribute value can also be set with a bang `*!` method
- user = User.new
- user.role.user!
- user.display_role == 'User'
+```ruby
+user = User.new
+user.role.user!
+user.display_role == 'User'
- user.role.author!
- user.display_role == 'Author'
+user.role.author!
+user.display_role == 'Author'
+```
-### Scopes for Models
+## Scopes for Models
Convenient scopes are created for each possible enum value on the model class:
- User.scope_admin == User.where(role: User::Role::ADMIN)
- User.scope_editor == User.where(role: User::Role::EDITOR)
- User.scope_author == User.where(role: User::Role::AUTHOR)
- User.scope_user == User.where(role: User::Role::USER)
+```ruby
+User.scope_admin == User.where(role: User::Role::ADMIN)
+User.scope_editor == User.where(role: User::Role::EDITOR)
+User.scope_author == User.where(role: User::Role::AUTHOR)
+User.scope_user == User.where(role: User::Role::USER)
+```
-### Enum Helper Methods
+## Enum Helper Methods
Helper methods are added to the actual `Enum` module as well.
-`get_label` and `get_key` get the (surprise!) label and key for a given enum
+### get_label and get_key
+Get the (surprise!) label and key for a given enum
value:
- User::Role.get_label(User::Role::ADMIN) == 'Admin'
- User::Role.get_key(User::Role::USER) == :user
+```ruby
+User::Role.get_label(User::Role::ADMIN) == 'Admin'
+User::Role.get_key(User::Role::USER) == :user
+```
----
+### attr_name
+Return the attribute name as a symbol
-`attr_name` returns the attribute symbol
+```ruby
+User::Role.attr_name == :role
+```
- User::Role.attr_name == :role
+### keys
+Return all the enum keys
----
+```ruby
+User::Role.keys == [:admin, :editor, :author, :user]
+```
-`keys` returns all the enum keys
+### values
+Return all the enum values
- User::Role.keys == [:admin, :editor, :author, :user]
+```ruby
+User::Role.values == [0, 1, 2, 3]
+```
----
+### labels
+Return all the enum labels
-`values` returns all the enum values
+```ruby
+User::Role.labels == ['Admin', 'Editor', 'Author', 'User']
+```
- User::Role.values == [0, 1, 2, 3]
-
----
-
-`labels` returns all the enum labels
-
- User::Role.labels == ['Admin', 'Editor', 'Author', 'User']
-
----
-
-`label_value_pairs` returns an array of pairs of the label and value for each
+### label_value_pairs
+Return an array of pairs of the label and value for each
enum value. This is mainly a convenience method for something like the
collection option for a select input in the
[Formtastic](https://github.com/justinfrench/formtastic) or
-[ActiveAdmin (which uses Formtastic)](https://github.com/gregbell/active_admin)
-gems:
+[ActiveAdmin](https://github.com/gregbell/active_admin) (which uses Formtastic)
+gems, so you can easily generate select options:
- User::Role.label_value_pairs ==
- [['Admin', 0], ['Editor', 1], ['Author', 2], ['User', 3]]
+```ruby
+User::Role.label_value_pairs == [
+ ['Admin', 0], ['Editor', 1], ['Author', 2], ['User', 3]
+]
----
+# In an ActiveAdmin form
+ActiveAdmin.register User do
+ form do |f|
+ f.inputs 'User Details' do
+ f.input :first_name
+ f.input :last_name
+ f.input :email
+ # Example usage of `label_value_pairs`
+ f.input :role, as: :select, collection: User::Role.label_value_pairs
+ end
+ end
+end
+```
+
+You can also filter the results by passing in enum value keys as symbol
+arguments:
+
+```ruby
+User::Role.label_value_pairs(:admin, :author) == [
+ ['Admin', 0], ['Author', 2]
+]
+```
+
+### to_h and to_json
`to_h` and `to_json` return a hash and a json string representation of the enum,
respectively. They both offer an `only` and an `except` option to specify if
you only want the value or maybe only the label and key or if you want
everything but key. **NOTE**: passing only key to `only` or excluding all but
one key via `except` will give that single value (whether it's value, key, or
label) instead of a hash. See below to understand:
- # Default call with no options
- User::Role.to_h == {
- 'ADMIN' => { key: :admin, label: 'Admin', value: 0 },
- 'EDITOR' => { key: :editor, label: 'Editor', value: 1 },
- 'AUTHOR' => { key: :author, label: 'Author', value: 2 },
- 'USER' => { key: :user, label: 'User', value: 3 }
- }
+```ruby
+# Default call with no options
+User::Role.to_h == {
+ 'ADMIN' => { key: :admin, label: 'Admin', value: 0 },
+ 'EDITOR' => { key: :editor, label: 'Editor', value: 1 },
+ 'AUTHOR' => { key: :author, label: 'Author', value: 2 },
+ 'USER' => { key: :user, label: 'User', value: 3 }
+}
- # Call with a single symbol (would also work with `only: [:value]`)
- # Notice the mapped values are not hashes like above because we only
- # specified that we wanted the value
- User::Role.to_h(only: :value) == {
- 'ADMIN' => 0,
- 'EDITOR' => 1,
- 'AUTHOR' => 2,
- 'USER' => 3
- }
+# Call with a single symbol (would also work with `only: [:value]`)
+# Notice the mapped values are not hashes like above because we only
+# specified that we wanted the value
+User::Role.to_h(only: :value) == {
+ 'ADMIN' => 0,
+ 'EDITOR' => 1,
+ 'AUTHOR' => 2,
+ 'USER' => 3
+}
- # Would also work with `except: [:value]`
- User::Role.to_json(except: :value) ==
- "{\"ADMIN\":{\"key\":\"admin\",\"label\":\"Admin\"},\"EDITOR\":{\"key\":\"editor\",\"label\":\"Editor\"},\"AUTHOR\":{\"key\":\"author\",\"label\":\"Author\"},\"USER\":{\"key\":\"user\",\"label\":\"User\"}}"
+# Would also work with `except: [:value]`
+User::Role.to_json(except: :value) ==
+ "{\"ADMIN\":{\"key\":\"admin\",\"label\":\"Admin\"},\"EDITOR\":{\"key\":\"editor\",\"label\":\"Editor\"},\"AUTHOR\":{\"key\":\"author\",\"label\":\"Author\"},\"USER\":{\"key\":\"user\",\"label\":\"User\"}}"
+```
-### Feedback and Pull Requests Welcome
+## Feedback and Pull Requests Welcome
This is my first real Rails gem, so I welcome all feedback and ideas. I hope this gem is as helpful to you as it has been to me in my own projects.