ND::Enum
This gem allows you to create and use enums easily and quickly in your Rails project.
Installation
Install the gem and add to the application's Gemfile by executing:
$ bundle add nd-enum
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install nd-enum
Usage
- Basic usage
- Configuration
- I18n
- Validate translations presence
- Enforce translations presence
- ActiveRecord Enum
Basic usage
Define your enum in an ActiveRecord model:
class User < ApplicationRecord
nd_enum(role: %i(user admin))
end
It creates a module for your enum that contains one constant per enum value. Say goodbye to magic strings!
In our example, the module is User::Role
, and the constants are User::Role::USER
and User::Role::ADMIN
.
irb(main)> User::Role::USER
=> "user"
irb(main)> User::Role::ADMIN
=> "admin"
irb(main)> User::Role.all
=> ["user", "admin"]
irb(main)> User::Role.length
=> 2
irb(main)> User::Role[1]
=> "admin"
irb(main)> User::Role[:user]
=> "user"
irb(main)> User::Role.include?('foobar')
=> false
irb(main)> User::Role.include?('user')
=> true
ND::Enum inheritates from Enumerable
, so it is possible to use all Enumerable
methods on the enum module: each
, map
, find
...
Configuration
Fine-tune ND::Enum
behaviour by creating an initializer (for example: config/initializers/nd_enum.rb
).
The values shown in the example below are the default values.
ND::Enum.configure do |c|
c.default_i18n_scope = :base
c.default_i18n_validation_mode = :ignore # Allowed values: ignore, log, enforce
end
I18n
Allows to translate your enum values. Add to your locale files:
en:
users: # Model.table_name
role: # attribute
base: # default scope
user: User
admin: Admin
foobar: # custom scope
user: The user
admin: The admin
Then call t
(or translate
) method:
irb(main)> User::Role.t(:user) # Or `translate` method (alias)
=> "translation missing: en.users.role.base.user"
Use a different scope to have several translations for a single value, depending on context:
irb(main)> User::Role.t(:user, :foobar)
=> "translation missing: en.users.role.foobar.user"
Please note that the default scope (base
) can be configured using the default_i18n_scope
initializer option.
Validate translations presence
Validate that your enum are translated. By default, this feature is disabled.
class User < ApplicationRecord
nd_enum(role: %i(user admin), i18n: { mode: :log })
end
It will log the missing translations for each scope & locale. For example:
I, [2022-08-10T21:17:53.931669 #67401] INFO -- : ND::Enum: User#role scopes=[:base, :short]
I, [2022-08-10T21:17:53.931669 #67401] INFO -- : ND::Enum: User#role locale=en missing_keys=[]
I, [2022-08-10T21:17:53.931669 #67401] INFO -- : ND::Enum: User#role locale=nl missing_keys=["users.role.base.user", "users.role.short.user"]
This mode can be used as default with the c.default_i18n_validation_mode = :log
initializer option.
Enforce translations presence
Raise an exception when some translations are missing.
class User < ApplicationRecord
nd_enum(role: %i(user admin), i18n: { mode: :enforce })
end
(irb):1:in `<main>': One or several translations are missing (ND::Enum::MissingTranslationError)
from bin/console:15:in `<main>'
This mode can be used as default with the c.default_i18n_validation_mode = :enforce
initializer option.
ActiveRecord
Enum
Add a wrapper to ActiveRecord
Enum by specifying the db: true
option.
class User < ApplicationRecord
nd_enum(role: %i(user admin), db: true)
end
# It does exactly the same thing than below, but shorter:
class User < ApplicationRecord
nd_enum(role: %i(user admin))
enum(role: User::Role.to_h) # Or `enum(role: { user: 'user', admin: 'admin '})`
end
It allows to use these methods:
user.admin!
user.admin? # => true
user.role # => "admin"
And these scopes:
User.admin
User.not_admin
User.user
User.not_user
# ...
Disable scope definition by setting scopes: false
to your enum:
class User < ApplicationRecord
nd_enum(role: %i(user admin), db: { scopes: false })
end
Set the default enum:
class User < ApplicationRecord
nd_enum(role: %i(user admin), db: { default: :admin })
end
Add a prefix
or suffix
option when you need to define multiple enums with same values. If the passed value is true, the methods are prefixed/suffixed with the name of the enum. It is also possible to supply a custom value:
class User < ApplicationRecord
nd_enum(role: %i(user admin), db: { prefix: true })
# Scopes: `User.role_admin`, `User.role_user` ...
# Methods: `User.role_admin!`, `User.role_user!` ...
nd_enum(role: %i(user admin), db: { suffix: true })
# Scopes: `User.admin_role`, `User.user_role` ...
# Methods: `User.admin_role!`, `User.user_role!` ...
nd_enum(role: %i(user admin), db: { prefix: 'foobar' })
# Scopes: `User.foobar_admin`, `User.foobar_user` ...
# Methods: `User.foobar_admin!`, `User.foobar_user!` ...
end
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
Guard is also installed: bundle exec guard
.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, run gem bump
(or manually update the version number in version.rb
), and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/rclavel/nd-enum.
License
The gem is available as open source under the terms of the MIT License.