Skip to content

Commit 148a2cc

Browse files
authored
Merge pull request #61 from clio/fix_has_many_has_one_assign_logic
Write attribute with polymorphic integer type
2 parents 40e2b27 + 2164bf3 commit 148a2cc

File tree

8 files changed

+85
-6
lines changed

8 files changed

+85
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ tmp
2020
.byebug_history
2121
polymorphic_integer_type_test
2222
gemfiles/*.lock
23+
.idea/

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### Changed
2+
3+
## v3.2.1 (2023-12-14)
4+
5+
### Fixed
6+
7+
- Not proper assigning polymorphic value with `has_many` and `has_one` reflection.
8+
9+
### Added
10+
11+
- Added .idea/ folder to .gitignore
12+
13+
### Changed

lib/polymorphic_integer_type.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require "polymorphic_integer_type/module_generator"
77
require "polymorphic_integer_type/belongs_to_polymorphic_association_extension"
88
require "polymorphic_integer_type/activerecord_5_0_0/polymorphic_array_value_extension"
9+
require "polymorphic_integer_type/polymorphic_foreign_association_extension"
910

1011
if ACTIVE_RECORD_VERSION < Gem::Version.new("5.2.0")
1112
require "polymorphic_integer_type/activerecord_5_0_0/association_query_handler_extension"

lib/polymorphic_integer_type/extensions.rb

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module PolymorphicIntegerType
22

33
module Extensions
44
module ClassMethods
5+
ActiveRecord::Reflection::HasManyReflection.attr_accessor(:foreign_integer_type)
6+
ActiveRecord::Reflection::HasManyReflection.attr_accessor(:integer_type)
7+
ActiveRecord::Reflection::HasOneReflection.attr_accessor(:foreign_integer_type)
8+
ActiveRecord::Reflection::HasOneReflection.attr_accessor(:integer_type)
59

610
def belongs_to(name, scope = nil, **options)
711
options = scope if scope.kind_of? Hash
@@ -64,8 +68,10 @@ def remove_type_and_establish_mapping(name, options, scope)
6468
condition = instance_exec(&scope).merge(condition) if scope.is_a?(Proc)
6569
condition
6670
}
71+
return foreign_type, klass_mapping.to_i
6772
else
6873
options[:scope] ||= scope
74+
return nil, nil
6975
end
7076
end
7177

@@ -86,8 +92,10 @@ def has_many(name, scope = nil, **options, &extension)
8692
scope = nil
8793
end
8894

89-
remove_type_and_establish_mapping(name, options, scope)
90-
super(name, options.delete(:scope), **options, &extension)
95+
integer_type_values = remove_type_and_establish_mapping(name, options, scope)
96+
super(name, options.delete(:scope), **options, &extension).tap do
97+
remove_integer_type_and_set_attributes_and_extension(integer_type_values, reflections[name.to_s])
98+
end
9199
end
92100

93101
def has_one(name, scope = nil, **options)
@@ -96,8 +104,27 @@ def has_one(name, scope = nil, **options)
96104
scope = nil
97105
end
98106

99-
remove_type_and_establish_mapping(name, options, scope)
100-
super(name, options.delete(:scope), **options)
107+
integer_type_values = remove_type_and_establish_mapping(name, options, scope)
108+
super(name, options.delete(:scope), **options).tap do
109+
remove_integer_type_and_set_attributes_and_extension(integer_type_values, reflections[name.to_s])
110+
end
111+
end
112+
113+
def remove_integer_type_and_set_attributes_and_extension(integer_type_values, reflection)
114+
foreign_integer_type = integer_type_values[0]
115+
integer_type = integer_type_values[1]
116+
is_polymorphic_integer = foreign_integer_type && integer_type
117+
118+
if is_polymorphic_integer
119+
reflection.foreign_integer_type = foreign_integer_type
120+
reflection.integer_type = integer_type
121+
122+
if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new("6.1")
123+
ActiveRecord::Associations::Association.prepend(PolymorphicIntegerType::PolymorphicForeignAssociationExtension)
124+
else
125+
ActiveRecord::Associations::ForeignAssociation.prepend(PolymorphicIntegerType::PolymorphicForeignAssociationExtension)
126+
end
127+
end
101128
end
102129

103130

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module PolymorphicIntegerType
2+
module PolymorphicForeignAssociationExtension
3+
4+
def set_owner_attributes(record)
5+
super
6+
if reflection.foreign_integer_type && reflection.integer_type
7+
record._write_attribute(reflection.foreign_integer_type, reflection.integer_type)
8+
end
9+
end
10+
end
11+
end
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module PolymorphicIntegerType
2-
VERSION = "3.2.0"
2+
VERSION = "3.2.1"
33
end

spec/polymorphic_integer_type_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,28 @@
2626
expect(link.target_type).to eq("Food")
2727
end
2828

29+
context "from HasManyReflection" do
30+
it "sets the source properly HasManyReflection" do
31+
link_1 = Link.create()
32+
link_2 = Link.create()
33+
dog.source_links = [link_1, link_2]
34+
expect(link_1.source_type).to eq("Animal")
35+
expect(link_1.source_id).to eq(dog.id)
36+
expect(link_2.source_type).to eq("Animal")
37+
expect(link_1.source_id).to eq(dog.id)
38+
end
39+
end
40+
41+
context "from HasOneReflection" do
42+
it "sets the source properly HasOneReflection" do
43+
link = Link.create()
44+
dog.source_link = link
45+
46+
expect(link.source_type).to eq("Animal")
47+
expect(link.source_id).to eq(dog.id)
48+
end
49+
end
50+
2951
context "when models are namespaced" do
3052
context "and mappings include namespaces" do
3153
it "sets the source_type" do
@@ -340,6 +362,10 @@ class InlineDrink2 < ActiveRecord::Base
340362
expect(link[:target_type]).to eq(13)
341363
end
342364

365+
it "pulls mapping from given hash" do
366+
animal.source_links.new
367+
end
368+
343369
it "doesn't break string type polymorphic associations" do
344370
expect(link.normal_target).to eq(drink)
345371
expect(link.normal_target_type).to eq("InlineDrink2")

spec/support/animal.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ class Animal < ActiveRecord::Base
33

44
belongs_to :owner, class_name: "Person"
55
has_many :source_links, as: :source, integer_type: true, class_name: "Link"
6-
6+
has_one :source_link, as: :source, integer_type: true, class_name: "Link"
77
end

0 commit comments

Comments
 (0)