diff --git a/.gitignore b/.gitignore index 35bf47d..1abc64e 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ tmp .byebug_history polymorphic_integer_type_test gemfiles/*.lock +.idea/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e7cb58e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +### Changed + +## v3.2.1 (2023-12-14) + +### Fixed + +- Not proper assigning polymorphic value with `has_many` and `has_one` reflection. + +### Added + +- Added .idea/ folder to .gitignore + +### Changed \ No newline at end of file diff --git a/lib/polymorphic_integer_type.rb b/lib/polymorphic_integer_type.rb index a68099c..b5bf33d 100644 --- a/lib/polymorphic_integer_type.rb +++ b/lib/polymorphic_integer_type.rb @@ -6,6 +6,7 @@ require "polymorphic_integer_type/module_generator" require "polymorphic_integer_type/belongs_to_polymorphic_association_extension" require "polymorphic_integer_type/activerecord_5_0_0/polymorphic_array_value_extension" +require "polymorphic_integer_type/polymorphic_foreign_association_extension" if ACTIVE_RECORD_VERSION < Gem::Version.new("5.2.0") require "polymorphic_integer_type/activerecord_5_0_0/association_query_handler_extension" diff --git a/lib/polymorphic_integer_type/extensions.rb b/lib/polymorphic_integer_type/extensions.rb index 9d43529..c6c1389 100644 --- a/lib/polymorphic_integer_type/extensions.rb +++ b/lib/polymorphic_integer_type/extensions.rb @@ -2,6 +2,10 @@ module PolymorphicIntegerType module Extensions module ClassMethods + ActiveRecord::Reflection::HasManyReflection.attr_accessor(:foreign_integer_type) + ActiveRecord::Reflection::HasManyReflection.attr_accessor(:integer_type) + ActiveRecord::Reflection::HasOneReflection.attr_accessor(:foreign_integer_type) + ActiveRecord::Reflection::HasOneReflection.attr_accessor(:integer_type) def belongs_to(name, scope = nil, **options) options = scope if scope.kind_of? Hash @@ -64,8 +68,10 @@ def remove_type_and_establish_mapping(name, options, scope) condition = instance_exec(&scope).merge(condition) if scope.is_a?(Proc) condition } + return foreign_type, klass_mapping.to_i else options[:scope] ||= scope + return nil, nil end end @@ -86,8 +92,10 @@ def has_many(name, scope = nil, **options, &extension) scope = nil end - remove_type_and_establish_mapping(name, options, scope) - super(name, options.delete(:scope), **options, &extension) + integer_type_values = remove_type_and_establish_mapping(name, options, scope) + super(name, options.delete(:scope), **options, &extension).tap do + remove_integer_type_and_set_attributes_and_extension(integer_type_values, reflections[name.to_s]) + end end def has_one(name, scope = nil, **options) @@ -96,8 +104,27 @@ def has_one(name, scope = nil, **options) scope = nil end - remove_type_and_establish_mapping(name, options, scope) - super(name, options.delete(:scope), **options) + integer_type_values = remove_type_and_establish_mapping(name, options, scope) + super(name, options.delete(:scope), **options).tap do + remove_integer_type_and_set_attributes_and_extension(integer_type_values, reflections[name.to_s]) + end + end + + def remove_integer_type_and_set_attributes_and_extension(integer_type_values, reflection) + foreign_integer_type = integer_type_values[0] + integer_type = integer_type_values[1] + is_polymorphic_integer = foreign_integer_type && integer_type + + if is_polymorphic_integer + reflection.foreign_integer_type = foreign_integer_type + reflection.integer_type = integer_type + + if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new("6.1") + ActiveRecord::Associations::Association.prepend(PolymorphicIntegerType::PolymorphicForeignAssociationExtension) + else + ActiveRecord::Associations::ForeignAssociation.prepend(PolymorphicIntegerType::PolymorphicForeignAssociationExtension) + end + end end diff --git a/lib/polymorphic_integer_type/polymorphic_foreign_association_extension.rb b/lib/polymorphic_integer_type/polymorphic_foreign_association_extension.rb new file mode 100644 index 0000000..2b18d05 --- /dev/null +++ b/lib/polymorphic_integer_type/polymorphic_foreign_association_extension.rb @@ -0,0 +1,11 @@ +module PolymorphicIntegerType + module PolymorphicForeignAssociationExtension + + def set_owner_attributes(record) + super + if reflection.foreign_integer_type && reflection.integer_type + record._write_attribute(reflection.foreign_integer_type, reflection.integer_type) + end + end + end +end diff --git a/lib/polymorphic_integer_type/version.rb b/lib/polymorphic_integer_type/version.rb index 7bd53b6..28ec6e3 100644 --- a/lib/polymorphic_integer_type/version.rb +++ b/lib/polymorphic_integer_type/version.rb @@ -1,3 +1,3 @@ module PolymorphicIntegerType - VERSION = "3.2.0" + VERSION = "3.2.1" end diff --git a/spec/polymorphic_integer_type_spec.rb b/spec/polymorphic_integer_type_spec.rb index 563fa49..3d56eb2 100644 --- a/spec/polymorphic_integer_type_spec.rb +++ b/spec/polymorphic_integer_type_spec.rb @@ -26,6 +26,28 @@ expect(link.target_type).to eq("Food") end + context "from HasManyReflection" do + it "sets the source properly HasManyReflection" do + link_1 = Link.create() + link_2 = Link.create() + dog.source_links = [link_1, link_2] + expect(link_1.source_type).to eq("Animal") + expect(link_1.source_id).to eq(dog.id) + expect(link_2.source_type).to eq("Animal") + expect(link_1.source_id).to eq(dog.id) + end + end + + context "from HasOneReflection" do + it "sets the source properly HasOneReflection" do + link = Link.create() + dog.source_link = link + + expect(link.source_type).to eq("Animal") + expect(link.source_id).to eq(dog.id) + end + end + context "when models are namespaced" do context "and mappings include namespaces" do it "sets the source_type" do @@ -340,6 +362,10 @@ class InlineDrink2 < ActiveRecord::Base expect(link[:target_type]).to eq(13) end + it "pulls mapping from given hash" do + animal.source_links.new + end + it "doesn't break string type polymorphic associations" do expect(link.normal_target).to eq(drink) expect(link.normal_target_type).to eq("InlineDrink2") diff --git a/spec/support/animal.rb b/spec/support/animal.rb index ca7db21..3a83839 100644 --- a/spec/support/animal.rb +++ b/spec/support/animal.rb @@ -3,5 +3,5 @@ class Animal < ActiveRecord::Base belongs_to :owner, class_name: "Person" has_many :source_links, as: :source, integer_type: true, class_name: "Link" - + has_one :source_link, as: :source, integer_type: true, class_name: "Link" end \ No newline at end of file