From a0b4e2cfdd0115805823151a8e89e20fc9aac922 Mon Sep 17 00:00:00 2001 From: Karl Glaser Date: Mon, 8 Feb 2016 22:59:28 +1100 Subject: [PATCH 1/2] Switch the hash being modified in changed_attributes This will throw in rails 4 --- lib/delegates_attributes_to.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/delegates_attributes_to.rb b/lib/delegates_attributes_to.rb index 220b196..8219845 100644 --- a/lib/delegates_attributes_to.rb +++ b/lib/delegates_attributes_to.rb @@ -135,8 +135,8 @@ def changed_attributes result.merge! delegated_attribute => association_changed_attributes[attribute] end changed_attributes = super - changed_attributes.merge!(result) - changed_attributes + result.merge! changed_attributes + result end end end From 7fa3e66ee92b3d6ab0f7ec6a9eba72ed32a4891c Mon Sep 17 00:00:00 2001 From: Isaac Norman Date: Mon, 13 May 2019 12:54:56 +1000 Subject: [PATCH 2/2] Move to new `prepend` method rather than `alias_method_chain` As it does not work in Rail 5.1. See https://littlelines.com/blog/2018/01/31/replace-alias-method-chain --- lib/delegates_attributes_to.rb | 59 +++++++++++++++++----------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/lib/delegates_attributes_to.rb b/lib/delegates_attributes_to.rb index 8219845..776f8bc 100644 --- a/lib/delegates_attributes_to.rb +++ b/lib/delegates_attributes_to.rb @@ -1,4 +1,34 @@ +module DelegatesAttributesToWithExtras + def assign_multiparameter_attributes(pairs) + delegated_pairs = {} + original_pairs = [] + + pairs.each do |name, value| + # it splits multiparameter attribute + # 'published_at(2i)' => ['published_at(2i)', 'published_at', '(2i)'] + # 'published_at' => ['published_at', 'published_at', nil ] + __, delegated_attribute, suffix = name.match(/^(\w+)(\([0-9]*\w\))?$/).to_a + association, attribute = self.class.delegated_attributes[delegated_attribute] + + if association + (delegated_pairs[association] ||= {})["#{attribute}#{suffix}"] = value + else + original_pairs << [name, value] + end + end + + delegated_pairs.each do |association, attributes| + association_object = send(association) || send("build_#{association}") + # let association_object handle its multiparameter attributes + association_object.attributes = attributes + end + + super(original_pairs) + end +end + module DelegatesAttributesTo + prepend DelegatesAttributesToWithExtras DEFAULT_REJECTED_COLUMNS = ['created_at','created_on','updated_at','updated_on','lock_version','type','id','position','parent_id','lft','rgt'].freeze DIRTY_SUFFIXES = ["_changed?", "_change", "_will_change!", "_was"].freeze @@ -7,8 +37,6 @@ def self.included(base) base.extend ClassMethods base.send :include, InstanceMethods - base.alias_method_chain :assign_multiparameter_attributes, :delegation - base.class_attribute :default_rejected_delegate_columns base.default_rejected_delegate_columns = DEFAULT_REJECTED_COLUMNS.dup @@ -90,33 +118,6 @@ module InstanceMethods private - def assign_multiparameter_attributes_with_delegation(pairs) - delegated_pairs = {} - original_pairs = [] - - pairs.each do |name, value| - # it splits multiparameter attribute - # 'published_at(2i)' => ['published_at(2i)', 'published_at', '(2i)'] - # 'published_at' => ['published_at', 'published_at', nil ] - __, delegated_attribute, suffix = name.match(/^(\w+)(\([0-9]*\w\))?$/).to_a - association, attribute = self.class.delegated_attributes[delegated_attribute] - - if association - (delegated_pairs[association] ||= {})["#{attribute}#{suffix}"] = value - else - original_pairs << [name, value] - end - end - - delegated_pairs.each do |association, attributes| - association_object = send(association) || send("build_#{association}") - # let association_object handle its multiparameter attributes - association_object.attributes = attributes - end - - assign_multiparameter_attributes_without_delegation(original_pairs) - end - def changed_attributes result = {} self.class.delegated_attributes.each do |delegated_attribute, (association, attribute)|