https://github.com/shkm/enummer
🏳️🌈 Multi enums (aka flags) for Rails
https://github.com/shkm/enummer
activerecord bitwise-enum enums flags rails ruby
Last synced: 4 months ago
JSON representation
🏳️🌈 Multi enums (aka flags) for Rails
- Host: GitHub
- URL: https://github.com/shkm/enummer
- Owner: shkm
- License: mit
- Created: 2021-12-07T08:21:46.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2025-07-30T08:17:56.000Z (7 months ago)
- Last Synced: 2025-10-19T19:54:53.723Z (4 months ago)
- Topics: activerecord, bitwise-enum, enums, flags, rails, ruby
- Language: Ruby
- Homepage:
- Size: 69.3 KB
- Stars: 41
- Watchers: 2
- Forks: 5
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: MIT-LICENSE
Awesome Lists containing this project
README
# Enummer
[](https://rubygems.org/gems/enummer)
[](https://app.codecov.io/gh/shkm/enummer)
[](https://github.com/shkm/enummer/blob/main/MIT-LICENSE)
[](https://www.rubydoc.info/github/shkm/enummer/main)
Enummer is a lightweight answer for adding enums with multiple values to Rails, with a similar syntax to Rails' built-in `enum`.
Enummer officially supports Ruby versions 2.7, 3.0 and 3.1 with SQLite, PostgreSQL, and MariaDB.
## Installation
Add `gem "enummer"` to your Gemfile and `bundle`.
## Usage
### Setup
Create a migration for an integer that looks something like this:
```ruby
class CreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
t.integer :permissions, default: 0, null: false
end
end
end
```
Now set up enummer with the available values in your model:
```ruby
enummer permissions: %i[read write execute]
```
Similar to `enum`, enummer can also be initialized with a hash, where the numeric index represents the position of the bit that maps to the flag:
```ruby
enummer permissions: {
read: 0,
write: 1,
execute: 2
}
```
This makes it easier to add/remove entries without worrying about migrating historical data.
### Scopes
Scopes will now be provided for `` and `not_`.
```ruby
User.read
User.not_read
User.write
User.not_write
User.execute
User.not_execute
```
Additionally, a `with_` scope will be generated which returns all records that match all given options. E.g.:
```ruby
user1 = User.create!(permissions: %i[read write execute])
user2 = User.create!(permissions: %i[read write])
user3 = User.create!(permissions: %i[read])
# .where(permissions: ...) will generate an `IN` query, returning all records that have *any*
# of those permissions.
User.where(permissions: %i[read write]) # => [user1, user2, user3]
# .with_permissions will return only users that have at least all of the given set of permissions
User.with_permissions(%i[read write]) # => [user1, user2]
```
### Getter methods
Simply calling the instance method for the column will return an array of options. Question mark methods are also provided.
```ruby
user = User.last
user.permissions # => [:read, :write]
user.read? # => true
user.write? # => true
user.execute? # => false
```
### Setter methods
Options can be set with an array of symbols or via bang methods. Bang methods will additionally persist the changes.
```ruby
user.update(permissions: %i[read write])
user.write!
```
## FAQ
### Which data type should I use?
That depends on how many options you expect to store. [In PostgreSQL](https://www.postgresql.org/docs/9.1/datatype-numeric.html) you should be able to store `bytes * 8 - 1` of your data type:
| Type | Bytes | Values |
| -------- | ----- | ----------- |
| smallint | 2 | 15 |
| integer | 4 | 31 |
| bigint | 8 | 65 |
| numeric | ??? | all of them |
### How can I use it outside of Rails?
lol stop
## Contributing
Make an issue / PR and we'll see.
### Development
```bash
$ cd enummer
$ bundle config set without 'postgres mysql'
$ bundle install
$ cd test/dummy
$ RAILS_ENV=test DATABASE_URL=sqlite3:dummy_test bundle exec rails db:setup
$ cd ../..
$ RAILS_ENV=test DATABASE_URL=sqlite3:dummy_test bundle exec bin/test
```
## Alternatives
- [flag_shih_tzu](https://github.com/pboling/flag_shih_tzu)
- Lots of booleans
- DB Arrays
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).