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.
Usage
Here's an example given a class User with an attribute role:
# Example model User for a blog app
class User < ActiveRecord::Base
extend RailsAttrEnum
attr_enum :role, :admin, :author, :editor, :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::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.
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.
# Target specific identifiers
class User < ActiveRecord::Base
extend RailsAttrEnum
attr_enum :role, :admin, { author: 12 }, :editor, { user: 42 }
end
User::Role::ADMIN == 0
User::Role::AUTHOR == 12
User::Role::EDITOR == 1 # Notice this still defaulted to 1
User::Role::USER == 42
# Use a hash to specify all values
class User < ActiveRecord::Base
extend RailsAttrEnum
attr_enum :role, {
admin: 1,
author: 2,
editor: 4,
user: 8
}
end
User::Role::ADMIN == 1
User::Role::AUTHOR == 2
User::Role::EDITOR == 4
User::Role::USER == 8
# Use a block to specify some (or all)
class User < ActiveRecord::Base
extend RailsAttrEnum
attr_enum :role do
add admin: 42
add :author
add :editor
add user: 7
end
end
User::Role::ADMIN == 42
User::Role::AUTHOR == 0 # Again notice how `AUTHOR` and `EDITOR` defaulted
User::Role::EDITOR == 1
User::Role::USER == 7
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.
class User < ActiveRecord::Base
extend RailsAttrEnum
attr_enum :role, :admin, :author, :editor, :user
end
User::Role::ADMIN_LABEL == 'Admin'
User::Role::AUTHOR_LABEL == 'Author'
User::Role::EDITOR_LABEL == 'Editor'
User::Role::USER_LABEL == 'User'
user = User.new(role: User::Role::ADMIN)
user.display_role == 'Admin' # Helper method added by RailsAttrEnum
You can specify your own labels if you like. By default, RailAttrEnum calls
.to_s.titleize on the symbol identifier.
class User < ActiveRecord::Base
extend RailsAttrEnum
attr_enum :role,
{ admin: 'Admin Role' }, :author, { editor: 'Editor Role' }, :user
end
User::Role::ADMIN_LABEL == 'Admin Role'
User::Role::AUTHOR_LABEL == 'Author'
User::Role::EDITOR_LABEL == 'Editor Role'
User::Role::USER_LABEL == 'User'
# With a hash
class User < ActiveRecord::Base
extend RailsAttrEnum
attr_enum :role, {
admin: 'Admin Role',
author: 'Author Role',
editor: 'Editor Role',
user: 'User Role'
}
end
User::Role::ADMIN_LABEL == 'Admin Role'
User::Role::AUTHOR_LABEL == 'Author Role'
User::Role::EDITOR_LABEL == 'Editor Role'
User::Role::USER_LABEL == 'User Role'
# With a block
class User < ActiveRecord::Base
extend RailsAttrEnum
attr_enum :role do
add :admin
add author: 'Author Role'
add editor: 'Editor Role'
add :user
end
end
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.
class User < ActiveRecord::Base
extend RailsAttrEnum
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'