diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 5f2acd014d..0c3d5ea701 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -294,7 +294,7 @@ def define_attribute_method(attr_name, _owner: generated_attribute_methods) generate_method = "define_method_#{matcher.target}" if respond_to?(generate_method, true) - send(generate_method, attr_name.to_s) + send(generate_method, attr_name.to_s, owner: owner) else define_proxy_call true, owner, method_name, matcher.target, attr_name.to_s end @@ -354,14 +354,23 @@ def initialize(owner, path, line) @path = path @line = line @sources = ["# frozen_string_literal: true\n"] + @renames = {} end def <<(source_line) @sources << source_line end + def rename_method(old_name, new_name) + @renames[old_name] = new_name + end + def execute @owner.module_eval(@sources.join(";"), @path, @line - 1) + @renames.each do |old_name, new_name| + @owner.alias_method new_name, old_name + @owner.undef_method old_name + end end end private_constant :CodeGenerator @@ -527,7 +536,7 @@ module AttrNames # :nodoc: # to allocate an object on each call to the attribute method. # Making it frozen means that it doesn't get duped when used to # key the @attributes in read_attribute. - def self.define_attribute_accessor_method(mod, attr_name, writer: false) + def self.define_attribute_accessor_method(owner, attr_name, writer: false) method_name = "#{attr_name}#{'=' if writer}" if attr_name.ascii_only? && DEF_SAFE_NAME.match?(attr_name) yield method_name, "'#{attr_name}'" @@ -538,8 +547,7 @@ def self.define_attribute_accessor_method(mod, attr_name, writer: false) temp_method_name = "__temp__#{safe_name}#{'=' if writer}" attr_name_expr = "::ActiveModel::AttributeMethods::AttrNames::#{const_name}" yield temp_method_name, attr_name_expr - mod.alias_method method_name, temp_method_name - mod.undef_method temp_method_name + owner.rename_method(temp_method_name, method_name) end end end diff --git a/activemodel/lib/active_model/attributes.rb b/activemodel/lib/active_model/attributes.rb index 8655ab8ca0..e5db918d86 100644 --- a/activemodel/lib/active_model/attributes.rb +++ b/activemodel/lib/active_model/attributes.rb @@ -42,17 +42,14 @@ def attribute_names end private - def define_method_attribute=(name) + def define_method_attribute=(name, owner:) ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method( - generated_attribute_methods, name, writer: true, + owner, name, writer: true, ) do |temp_method_name, attr_name_expr| - generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 - # frozen_string_literal: true - def #{temp_method_name}(value) - name = #{attr_name_expr} - write_attribute(name, value) - end - RUBY + owner << + "def #{temp_method_name}(value)" << + " write_attribute(#{attr_name_expr}, value)" << + "end" end end diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index f8bc1b6110..0a95dd48db 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -7,17 +7,14 @@ module Read module ClassMethods # :nodoc: private - def define_method_attribute(name) + def define_method_attribute(name, owner:) ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method( - generated_attribute_methods, name + owner, name ) do |temp_method_name, attr_name_expr| - generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 - # frozen_string_literal: true - def #{temp_method_name} - name = #{attr_name_expr} - _read_attribute(name) { |n| missing_attribute(n, caller) } - end - RUBY + owner << + "def #{temp_method_name}" << + " _read_attribute(#{attr_name_expr}) { |n| missing_attribute(n, caller) }" << + "end" end end end diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb index 937ca0e8aa..0e8a6f9ca0 100644 --- a/activerecord/lib/active_record/attribute_methods/write.rb +++ b/activerecord/lib/active_record/attribute_methods/write.rb @@ -11,17 +11,14 @@ module Write module ClassMethods # :nodoc: private - def define_method_attribute=(name) + def define_method_attribute=(name, owner:) ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method( - generated_attribute_methods, name, writer: true, + owner, name, writer: true, ) do |temp_method_name, attr_name_expr| - generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1 - # frozen_string_literal: true - def #{temp_method_name}(value) - name = #{attr_name_expr} - _write_attribute(name, value) - end - RUBY + owner << + "def #{temp_method_name}(value)" << + " _write_attribute(#{attr_name_expr}, value)" << + "end" end end end