https://github.com/jaynetics/denormalize_fields
Denormalizes ActiveRecord fields from one record to another
https://github.com/jaynetics/denormalize_fields
activerecord denormalization rails
Last synced: about 1 month ago
JSON representation
Denormalizes ActiveRecord fields from one record to another
- Host: GitHub
- URL: https://github.com/jaynetics/denormalize_fields
- Owner: jaynetics
- License: mit
- Created: 2020-02-13T11:11:23.000Z (over 6 years ago)
- Default Branch: main
- Last Pushed: 2023-07-23T05:32:19.000Z (almost 3 years ago)
- Last Synced: 2026-04-27T22:09:01.843Z (about 2 months ago)
- Topics: activerecord, denormalization, rails
- Language: Ruby
- Size: 55.7 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# DenormalizeFields
[](http://badge.fury.io/rb/denormalize_fields)
[](https://github.com/jaynetics/denormalize_fields/actions)
This gem adds a `denormalize` option to ActiveRecord relation definitions, so that updates on one record are forwarded to its dependent records.
Tested on Rails 7, but should work down to Rails 4.1.
## Installation
Add, install or require `denormalize_fields`.
## Usage
Either:
```ruby
class User < ApplicationRecord
has_many :posts, denormalize: { fields: %i[first_name last_name] }
end
```
Or:
```ruby
DenormalizeFields.denormalize(
fields: %i[first_name last_name],
from: User,
onto: :posts,
)
```
Resulting behavior:
```ruby
User.first.posts.pluck(:first_name) # => ['Igor', 'Igor']
User.first.update!(first_name: 'Wanja')
User.first.posts.pluck(:first_name) # => ['Wanja', 'Wanja']
```
Any validation errors in denormalized fields of dependent records are bubbled up to the source record.
There is also a `prefix` option:
```ruby
# assuming there is Rapper#name and Car#owner_name
class Rapper < ApplicationRecord
has_many :cars, denormalize: { fields: :name, prefix: :owner_ } }
end
```
Alternatively `fields` also accepts a `Hash` to map to other fields on the related record:
```ruby
# assuming there is Rapper#name and Car#owner
class Rapper < ApplicationRecord
has_many :cars, denormalize: { fields: { name: :owner } }
end
# multiple fields can be mapped to one, their values will be joined with " "
class Rapper < ApplicationRecord
has_many :cars, denormalize: { fields: { %i[first_name last_name] => :owner } }
end
```
Conditional denormalization is also supported:
```ruby
class Blog < ApplicationRecord
# don't remove topic from posts when it is removed from blog
has_many :posts, denormalize: { fields: :topic, if: :topic? }
end
```
## Caveats
- only works with fields that are in the database, no virtual attributes etc.
- does not work with `has_and_belongs_to_many` associations
- is based on `ActiveRecord` callbacks, so does not work for `#update_column` etc.
- does no denormalization when related records are first created / connected
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/jaynetics/denormalize_fields.
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
## Comparison with similar projects
Most of these have not been updated in years. Let me know if there is any cool new stuff.
- https://github.com/ursm/activerecord-denormalize
- similar goal
- runs custom SQL, so does not work with all DBs
- skips validations of related records
- only supports `has_many` relations, not `has_one` or `belongs_to`
- https://github.com/bebanjo/persistize
- for denormalization onto the *same* record or owner record only
- https://github.com/ignu/denormalize-field
- for denormalization onto the *same* record or owner record only
- postgres only
- https://github.com/logandk/mongoid_denormalize
- similar goal
- mongoid only