Skip to content

Commit

Permalink
Merge pull request #61 from clio/fix_has_many_has_one_assign_logic
Browse files Browse the repository at this point in the history
Write attribute with polymorphic integer type
  • Loading branch information
wendy-clio authored Dec 15, 2023
2 parents 40e2b27 + 2164bf3 commit 148a2cc
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ tmp
.byebug_history
polymorphic_integer_type_test
gemfiles/*.lock
.idea/
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions lib/polymorphic_integer_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
35 changes: 31 additions & 4 deletions lib/polymorphic_integer_type/extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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)
Expand All @@ -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


Expand Down
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion lib/polymorphic_integer_type/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module PolymorphicIntegerType
VERSION = "3.2.0"
VERSION = "3.2.1"
end
26 changes: 26 additions & 0 deletions spec/polymorphic_integer_type_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion spec/support/animal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 148a2cc

Please sign in to comment.