Why flag_shih_tzu is changing its default SQL for bit flags
Source: Dev.to
Background
flag_shih_tzu stores many boolean attributes in a single integer column, assigning one bit per flag.
Version 1.0.0 introduced support for multi‑bit flags, ternary flags, and enum flags.
class User :warpdrive,
2 => :shields
end
The IN‑list Query Problem
Historically the gem generated an IN() list for querying a single flag:
SELECT * FROM users WHERE flags IN (1, 3);
This works while the application knows exactly two flags (values 1 and 3).
During a rolling deploy, however, new flags may be added:
class User :warpdrive,
2 => :shields,
3 => :premium
end
A migration (or background job) sets the new bit for existing rows:
UPDATE users
SET flags = flags | 4
WHERE created_at :warpdrive,
2 => :shields,
flag_query_mode: :in_list
The :in_list mode remains supported but is no longer the safest default.
Performance Considerations
- IN‑list queries can be faster on some databases and with certain indexes when the set of possible flag combinations is fixed and well‑known.
- Bit‑operator queries guarantee correctness when flags are added over time, especially during rolling deploys. They also work well with typical integer indexes.
Choose the mode that best matches your workload, but defaults should prioritize correctness.
Conclusion
flag_shih_tzu now defaults to :bit_operator because it reliably handles evolving flag sets, avoiding the pitfalls of static IN‑list queries during deployments. Use :in_list only when you have a stable flag set and have measured a performance benefit.