Last active
December 21, 2015 12:58
-
-
Save sobrinho/6309391 to your computer and use it in GitHub Desktop.
Track habtm changes on active record
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# See https://groups.google.com/forum/#!topic/rubyonrails-core/Lb9rBkZnZSo | |
module TrackHabtmChanges | |
def self.included(model) | |
model.after_initialize :track_habtm_initial_state | |
model.after_save :track_habtm_initial_state | |
end | |
def changes | |
super.merge(habtm_changes) | |
end | |
def changed_attributes | |
changed_attributes = super | |
habtm_changes.each do |key, (_, new)| | |
changed_attributes[key] = new | |
end | |
changed_attributes | |
end | |
protected | |
def track_habtm_initial_state | |
@habtm_initial_state = {} | |
self.class.reflect_on_all_associations.each do |association| | |
next unless association.macro == :has_and_belongs_to_many | |
method = "#{association.name.to_s.singularize}_ids" | |
@habtm_initial_state[method] = send(method) | |
end | |
end | |
def habtm_changes | |
@habtm_initial_state.inject({}) do |habtm_changes, (association, initial_state)| | |
current_state = send(association) | |
if initial_state != current_state | |
habtm_changes[association] = [initial_state, current_state] | |
end | |
habtm_changes | |
end | |
end | |
end |
Instead of this:
self.class.reflect_on_all_associations.each do |association|
next unless association.macro == :has_and_belongs_to_many
you can do this:
self.class.reflect_on_all_associations(:has_and_belongs_to_many).each do |association|
...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Warning: It is slow when you fetch hundreds of objects (n + 1)