No release in over 3 years
Low commit activity in last 3 years
This gem adds a `denormalize` option to ActiveRecord relation definitions, e.g. `has_many :foos, denormalize: { fields: :updated_at }`.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 7.0
>= 0
>= 0

Runtime

>= 4.1.14, < 8.0.0
 Project Readme

DenormalizeFields

Gem Version Build Status

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:

class User < ApplicationRecord
  has_many :posts, denormalize: { fields: %i[first_name last_name] }
end

Or:

DenormalizeFields.denormalize(
  fields: %i[first_name last_name],
  from:   User,
  onto:   :posts,
)

Resulting behavior:

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:

# 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:

# 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:

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.

Comparison with similar projects

Most of these have not been updated in years. Let me know if there is any cool new stuff.