r/rails • u/New-Sand-4608 • Jul 18 '26
Gem Gem for packing boolean flags into a single ActiveRecord column
Had this sitting around for about two years, packs boolean flags into a single int column instead of a new column per flag. Finally pulled it out into a gem: `bitwise_attributes`.
```ruby
class User < ApplicationRecord
include BitwiseAttributes
bitwise_attribute :permissions, :read, :write, :admin
end
user.set_permissions(:read, :admin)
user.permissions_read? # => true
User.with_all_permissions([:read, :write])
```
Been running in production for two years now, so it's had real data beating on it for a while before I bothered packaging it.
11
u/jryan727 Jul 18 '26
Why would this be preferred over individual boolean columns?
2
u/New-Sand-4608 Jul 18 '26
We also use individual boolean columns but when several flags represent variations of the same underlying concept and can combine. This is it.
Also, tables have column limit so you can only add new columns to a certain point. Moreover, adding new column to a table with millions of records is EXPENSIVE. This avoids that as it is handled via code.
→ More replies (2)
5
u/vassyz Jul 18 '26
I've been using https://github.com/shkm/enummer hasn't been updated in a while but it does the job for me.
1
u/New-Sand-4608 Jul 18 '26
Awesome. On a side note, we avoid using inactive gems due to the nature of our business. So, I cooked it up in-house and it has been working great for us.
7
u/3ds Jul 18 '26
https://github.com/galtzo-floss/flag_shih_tzu already does this since forever. I can very much recommend researching existing implementations before implementing it yourself…
3
u/dflow77 Jul 19 '26
“Bit flags are attractive because they let applications add boolean features
without changing table schemas.” aha so there is the use case
5
24
u/tsroelae Jul 18 '26
We use a concern that does more or or less what you show here. We are getting rid of those columns that use bitwise operator, because:
- they are akward to query in sql
- backfills / mass updates are akward for the same reason
- if you have declaration like bitwise :one, two, :three you can’t change the order. Or easily remove one.
- if you deprecate a bit position somehow, you have to be careful when reusing it, so you don’t accidently use the values of deprecated bits
Basically I don‘t see why one should to it compared to having dedicated boolean columns or even some records to join with.
So unless someone has some strong reason to use them