Skip to content

Commit 6677535

Browse files
committed
fix creating assocations with specs and add module generator
1 parent 72d5d8c commit 6677535

11 files changed

Lines changed: 89 additions & 54 deletions

lib/polymorphic_integer_type.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
require "polymorphic_integer_type/version"
44
require "polymorphic_integer_type/extensions"
55
require "polymorphic_integer_type/mapping"
6+
require "polymorphic_integer_type/module_generator"
7+
require "polymorphic_integer_type/belongs_to_polymorphic_association_extension"
68

79
if ACTIVE_RECORD_VERSION < Gem::Version.new("5")
810
require "polymorphic_integer_type/activerecord_4/predicate_builder_extension"
@@ -14,8 +16,4 @@
1416
require "polymorphic_integer_type/activerecord_5_0_0/association_query_handler_extension"
1517
end
1618

17-
if ACTIVE_RECORD_VERSION < Gem::Version.new("5.2.0")
18-
require "polymorphic_integer_type/activerecord_4/belongs_to_polymorphic_association_extension"
19-
end
20-
2119
module PolymorphicIntegerType; end

lib/polymorphic_integer_type/activerecord_4/belongs_to_polymorphic_association_extension.rb renamed to lib/polymorphic_integer_type/belongs_to_polymorphic_association_extension.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Associations
33
class BelongsToPolymorphicAssociation < BelongsToAssociation
44
private def replace_keys(record)
55
super
6-
owner[reflection.foreign_type] = record.class.base_class
6+
owner[reflection.foreign_type] = record.class
77
end
88
end
99
end

lib/polymorphic_integer_type/extensions.rb

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,11 @@ def belongs_to(name, scope = nil, **options)
2020
_polymorphic_foreign_types << foreign_type
2121

2222
# Required way to dynamically define a class method on the model
23-
singleton_class.__send__(:define_method, "#{foreign_type}_mapping") do
23+
define_singleton_method("#{foreign_type}_mapping") do
2424
mapping
2525
end
2626

27-
foreign_type_extension = Module.new do
28-
define_method foreign_type do
29-
t = super()
30-
self.class.send("#{foreign_type}_mapping")[t]
31-
end
32-
33-
define_method "#{foreign_type}=" do |klass|
34-
mapping = self.class.send("#{foreign_type}_mapping")
35-
enum = mapping.key(klass.to_s)
36-
if klass.kind_of?(Class) && klass <= ActiveRecord::Base
37-
enum ||= mapping.key(klass.polymorphic_name) if klass.respond_to?(:polymorphic_name)
38-
enum ||= mapping.key(klass.sti_name)
39-
enum ||= mapping.key(klass.base_class.to_s)
40-
enum ||= mapping.key(klass.base_class.sti_name)
41-
end
42-
enum ||= klass if klass != NilClass
43-
super(enum)
44-
end
45-
46-
define_method "#{name}=" do |record|
47-
super(record)
48-
send("#{foreign_type}=", record.class)
49-
association(name).loaded!
50-
end
51-
end
52-
53-
include(foreign_type_extension)
27+
ModuleGenerator.generate_and_include(self, foreign_type, name)
5428

5529
validate do
5630
t = send(foreign_type)

lib/polymorphic_integer_type/mapping.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ def self.[](as)
1515
@@mapping[as] || {}
1616
end
1717

18+
singleton_class.send(:alias_method, :[]=, :add)
1819
end
19-
2020
end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module PolymorphicIntegerType
2+
class ModuleGenerator
3+
def self.generate_and_include(klass,foreign_type, name)
4+
foreign_type_extension = Module.new do
5+
define_method foreign_type do
6+
t = super()
7+
self.class.send("#{foreign_type}_mapping")[t]
8+
end
9+
10+
define_method "#{foreign_type}=" do |klass|
11+
mapping = self.class.send("#{foreign_type}_mapping")
12+
enum = mapping.key(klass.to_s)
13+
if klass.kind_of?(Class) && klass <= ActiveRecord::Base
14+
enum ||= mapping.key(klass.polymorphic_name) if klass.respond_to?(:polymorphic_name)
15+
enum ||= mapping.key(klass.sti_name)
16+
enum ||= mapping.key(klass.base_class.to_s)
17+
enum ||= mapping.key(klass.base_class.sti_name)
18+
end
19+
enum ||= klass if klass != NilClass
20+
super(enum)
21+
end
22+
23+
define_method "#{name}=" do |record|
24+
super(record)
25+
send("#{foreign_type}=", record.class)
26+
association(name).loaded!
27+
end
28+
end
29+
30+
klass.include(foreign_type_extension)
31+
end
32+
end
33+
end
34+

polymorphic_integer_type.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ Gem::Specification.new do |spec|
2323
spec.add_development_dependency "rake"
2424
spec.add_development_dependency "rspec"
2525
spec.add_development_dependency "sqlite3"
26-
spec.add_development_dependency "byebug"
26+
spec.add_development_dependency "pry-byebug"
2727
end

spec/polymorphic_integer_type_spec.rb

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,51 @@
1414

1515
let(:link) { Link.create(source: source, target: target) }
1616

17+
18+
context "when creating associations" do
19+
it "sets the source_type" do
20+
link = dog.source_links.new
21+
expect(link.source_type).to eq("Animal")
22+
end
23+
24+
it "sets the target_type" do
25+
link = kibble.target_links.new
26+
expect(link.target_type).to eq("Food")
27+
end
28+
29+
context "when models are namespaced" do
30+
context "and mappings include namespaces" do
31+
it "sets the source_type" do
32+
allow(Link).to receive(:source_type_mapping).and_return({3 => "Namespaced::Plant"})
33+
allow(Link).to receive(:source_type_mapping2).and_return({3 => "Namespaced::Plant"})
34+
35+
link = Namespaced::Plant.create(name: "Oak").source_links.new
36+
expect(link.source_type).to eq("Namespaced::Plant")
37+
allow(Link).to receive(:source_type_mapping).and_return({1 => "Person", 2 => "Animal", 3 => "Plant"})
38+
end
39+
40+
it "sets the target_type" do
41+
allow(Link).to receive(:target_type_mapping).and_return({3 => "Namespaced::Activity"})
42+
link = Namespaced::Activity.create(name: "swaying").target_links.new
43+
expect(link.target_type).to eq("Namespaced::Activity")
44+
end
45+
end
46+
47+
context "and mappings don't include namespaces" do
48+
it "sets the source type" do
49+
Link.source_type_mapping
50+
link = Namespaced::Plant.create(name: "Oak").source_links.new
51+
expect(link.source_type).to eq("Plant")
52+
end
53+
54+
it "sets the target type" do
55+
link = Namespaced::Activity.create(name:"swaying").target_links.new
56+
expect(link.target_type).to eq("Activity")
57+
end
58+
end
59+
end
60+
end
61+
1762
context "when the source is nil" do
1863
let(:source) { nil }
1964
let(:target) { nil }
@@ -73,15 +118,6 @@
73118
it "properly finds the object with a find_by" do
74119
expect(Link.find_by(source: source, id: link.id)).to eql link
75120
end
76-
77-
context "when source and target are namedpaced without modifying polymorphic_name" do
78-
it "properly finds the object" do
79-
plant = Namespaced::Plant.create(name: "Mighty", kind: "Oak", owner: owner)
80-
activity = Namespaced::Activity.create(name: "swaying")
81-
link = Link.create(source: plant, target: activity)
82-
expect(Link.where(source: plant, id: link.id).first).to eql link
83-
end
84-
end
85121
end
86122

87123
shared_examples "proper source" do

spec/spec_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
require 'support/drink'
1313
require 'support/namespaced_activity'
1414
require 'byebug'
15+
require 'pry'
1516

1617
RSpec.configure do |config|
1718
config.before(:suite) do

spec/support/link.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,4 @@ class Link < ActiveRecord::Base
33

44
belongs_to :source, polymorphic: true, integer_type: true
55
belongs_to :target, polymorphic: true, integer_type: true
6-
7-
def source=(val)
8-
super(val)
9-
end
10-
11-
def source_type=(val)
12-
super(val)
13-
end
146
end

spec/support/namespaced_activity.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class Activity< ActiveRecord::Base
55
self.store_full_sti_class = false
66
self.table_name = "activities"
77

8-
has_many :target_links, as: :target, integer_type: true, class_name: "Link"
8+
has_many :target_links, as: :target, inverse_of: :target, integer_type: true, class_name: "Link"
99
end
1010
end
1111

0 commit comments

Comments
 (0)