README.md in rails_attr_enum-0.0.6 vs README.md in rails_attr_enum-0.1.0

- old
+ new

@@ -12,157 +12,159 @@ # Example model User for a blog app class User < ActiveRecord::Base extend RailsAttrEnum - attr_enum :role, :admin, :author, :editor, :user + attr_enum :role, :admin, :editor, :author, :user end # Creates module `User::Role` with constants for each possible value User::Role::ADMIN == 0 - User::Role::AUTHOR == 1 - User::Role::EDITOR == 2 + User::Role::EDITOR == 1 + User::Role::AUTHOR == 2 User::Role::USER == 3 -As you can see, this would give a module `User::Role` containing constants `ADMIN`, `AUTHOR`, -`EDITOR`, and `USER` with the respective values of `0`, `1`, `2`, and `3`. +[View other ways to define and customize enums](https://github.com/jfairbank/rails_attr_enum/wiki/Adding-an-Enum-to-a-Model) -You can also specify the integer values for each identifier or only some. Those -you don't specify will automatically be filled with the first available integer -value. +### Helpers for Model Instances - # Target specific identifiers - class User < ActiveRecord::Base - extend RailsAttrEnum +A couple helpers methods are added to the model and the enum attribute. - attr_enum :role, :admin, { author: 12 }, :editor, { user: 42 } - end +Get the "display" label for the current value with the `display_*` method: - User::Role::ADMIN == 0 - User::Role::AUTHOR == 12 - User::Role::EDITOR == 1 # Notice this still defaulted to 1 - User::Role::USER == 42 + user = User.new(User::Role::ADMIN) + user.display_role == 'Admin' - # Use a hash to specify all values - class User < ActiveRecord::Base - extend RailsAttrEnum +You can check for a specific value with a query `*?` method: - attr_enum :role, { - admin: 1, - author: 2, - editor: 4, - user: 8 - } - end + user = User.new(User::Role::AUTHOR) + user.role.admin? # false + user.role.editor? # false + user.role.author? # true + user.role.user? # false - User::Role::ADMIN == 1 - User::Role::AUTHOR == 2 - User::Role::EDITOR == 4 - User::Role::USER == 8 +The query method works via a forwarding class, so the normal `role` and `role=` +methods should work as expected. - # Use a block to specify some (or all) - class User < ActiveRecord::Base - extend RailsAttrEnum +**NOTE**: one caveat to this is if you try to use +a hash map of the enum values to some other value. See below: - attr_enum :role do - add admin: 42 - add :author - add :editor - add user: 7 - end - end + 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::Role::ADMIN == 42 - User::Role::AUTHOR == 0 # Again notice how `AUTHOR` and `EDITOR` defaulted - User::Role::EDITOR == 1 - User::Role::USER == 7 + user = User.new(User::Role::EDITOR) + alt_label = alt_label_map[user.role] + alt_label == nil # not 'An editor' -### Labels -RailsAttrEnum also creates a label for each identifier that you can use in your -app to display something meaningful for a value. Appropriate label constants are -added to the module enum as well as a helper `display_*` method on instances of -your model. +If you want the hash to work as expected than call the `.value` method on the +attribute: - class User < ActiveRecord::Base - extend RailsAttrEnum + alt_label = alt_label_map[user.role.value] + alt_label == 'An editor' - attr_enum :role, :admin, :author, :editor, :user - end +Thus, the `.value` method on the attribute gives the actual `Fixnum` value. +There is also a `.key` method which gives the symbol key: - User::Role::ADMIN_LABEL == 'Admin' - User::Role::AUTHOR_LABEL == 'Author' - User::Role::EDITOR_LABEL == 'Editor' - User::Role::USER_LABEL == 'User' + user = User.new(User::Role::ADMIN) + user.role.key == :admin - user = User.new(role: User::Role::ADMIN) - user.display_role == 'Admin' # Helper method added by RailsAttrEnum +The attribute value can also be set with a bang `*!` method -You can specify your own labels if you like. By default, RailAttrEnum calls -`.to_s.titleize` on the symbol identifier. + user = User.new + user.role.user! + user.display_role == 'User' - class User < ActiveRecord::Base - extend RailsAttrEnum + user.role.author! + user.display_role == 'Author' - attr_enum :role, - { admin: 'Admin Role' }, :author, { editor: 'Editor Role' }, :user - end +### Scopes for Models - User::Role::ADMIN_LABEL == 'Admin Role' - User::Role::AUTHOR_LABEL == 'Author' - User::Role::EDITOR_LABEL == 'Editor Role' - User::Role::USER_LABEL == 'User' +Convenient scopes are created for each possible enum value on the model class: - # With a hash - class User < ActiveRecord::Base - extend RailsAttrEnum + 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) - attr_enum :role, { - admin: 'Admin Role', - author: 'Author Role', - editor: 'Editor Role', - user: 'User Role' - } - end +### Enum Helper Methods - User::Role::ADMIN_LABEL == 'Admin Role' - User::Role::AUTHOR_LABEL == 'Author Role' - User::Role::EDITOR_LABEL == 'Editor Role' - User::Role::USER_LABEL == 'User Role' +Helper methods are added to the actual `Enum` module as well. - # With a block - class User < ActiveRecord::Base - extend RailsAttrEnum +`get_label` and `get_key` get the (surprise!) label and key for a given enum +value: - attr_enum :role do - add :admin - add author: 'Author Role' - add editor: 'Editor Role' - add :user - end - end + User::Role.get_label(User::Role::ADMIN) == 'Admin' + User::Role.get_key(User::Role::USER) == :user - User::Role::ADMIN_LABEL == 'Admin' - User::Role::AUTHOR_LABEL == 'Author Role' - User::Role::EDITOR_LABEL == 'Editor Role' - User::Role::USER_LABEL == 'User' +--- -### Mix-and-match -If you need to be very specific about values and labels, then you can specify -both at the same time too. +`attr_name` returns the attribute symbol - class User < ActiveRecord::Base - extend RailsAttrEnum + User::Role.attr_name == :role - attr_enum :role, { admin: { label: 'Admin Role', value: 1 } }, - { author: 'Author Role' }, - { editor: 42 }, - :user - end +--- - User::Role::ADMIN == 1 - User::Role::ADMIN_LABEL == 'Admin Role' - User::Role::AUTHOR == 0 - User::Role::AUTHOR_LABEL == 'Author Role' - User::Role::EDITOR == 42 - User::Role::EDITOR_LABEL == 'Editor' - User::Role::USER == 2 - User::Role::USER_LABEL == 'User' +`keys` returns all the enum keys + + User::Role.keys == [:admin, :editor, :author, :user] + +--- + +`values` returns all the enum values + + 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 +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: + + User::Role.label_value_pairs == + [['Admin', 0], ['Editor', 1], ['Author', 2], ['User', 3]] + +--- + +`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 } + } + + # 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\"}}" + +### 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.