finds.dev← search

// the find

jrochkind/attr_json

★ 608 · Ruby · MIT · updated Sep 2026

Serialized json-hash-backed ActiveRecord attributes, super smooth

attr_json lets ActiveRecord models declare typed attributes (string, integer, nested models, arrays of either) that get serialized into a single jsonb column instead of living as real columns, with casting and dirty tracking that mimics ordinary AR attributes. It's aimed at Rails/Postgres apps with variant or CMS-style data — STI subclasses with non-shared fields, plugin-configurable content types — where adding a column per field doesn't make sense.

It builds on ActiveModel::Type rather than rolling its own serializer, so attr_json fields get real casting (string->integer, array coercion, defaults) and work with Rails dirty tracking almost for free. jsonb_contains supports dot-keypath queries into nested AttrJson::Model structures and arrays, not just top-level keys, and maps directly onto a GIN index. Nested models are genuinely composable — you can build polymorphic object graphs several levels deep and round-trip them cleanly. The Appraisal-based CI matrix testing Rails 6.0 through edge is a real maintenance signal, not just a badge.

Saving any attr_json attribute rewrites the entire jsonb blob, not just the changed key, so concurrent writers will silently clobber each other unless you bolt on AR's optimistic locking yourself — easy to miss until it bites in production. Querying is limited to postgres `@>` containment: no `>`, `<`, ranges, or ordering on keypaths, so anything beyond exact-match filtering means denormalizing into real columns anyway. MySQL json columns are claimed to work but explicitly 'has not yet been tested,' so it's Postgres-only in practice. The test suite only runs inside a full Rails app via combustion, which makes the gem itself awkward to debug in isolation, and the maintainer is openly conservative about merging new features (partial jsonb merge updates have been an open issue since 2021), so gaps like that aren't likely to close soon.

View on GitHub →

// want more like this?

We dig through GitHub every week and send a few repos picked for what you actually care about — each with an honest take like this one.

Get finds in your inbox → Search again →