polyamorous 1.3.3 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/lib/polyamorous.rb +13 -40
- data/lib/polyamorous/activerecord_5.1_ruby_2/join_association.rb +1 -9
- data/lib/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb +2 -20
- data/lib/polyamorous/{activerecord_5.2_ruby_2 → activerecord_5.2.0_ruby_2}/join_association.rb +2 -10
- data/lib/polyamorous/{activerecord_5.2_ruby_2 → activerecord_5.2.0_ruby_2}/join_dependency.rb +3 -21
- data/lib/polyamorous/activerecord_5.2.0_ruby_2/reflection.rb +12 -0
- data/lib/polyamorous/activerecord_5.2.1_ruby_2/join_association.rb +22 -0
- data/lib/polyamorous/activerecord_5.2.1_ruby_2/join_dependency.rb +81 -0
- data/lib/polyamorous/activerecord_5.2.1_ruby_2/reflection.rb +2 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +2 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +81 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +2 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +2 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +2 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +2 -0
- data/lib/polyamorous/version.rb +1 -1
- data/polyamorous.gemspec +2 -4
- metadata +19 -49
- data/.gitignore +0 -6
- data/.travis.yml +0 -59
- data/Gemfile +0 -33
- data/LICENSE +0 -20
- data/README.md +0 -21
- data/Rakefile +0 -17
- data/lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_association.rb +0 -76
- data/lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_dependency.rb +0 -96
- data/lib/polyamorous/activerecord_4.1_ruby_1.9/join_association.rb +0 -2
- data/lib/polyamorous/activerecord_4.1_ruby_1.9/join_dependency.rb +0 -4
- data/lib/polyamorous/activerecord_4.1_ruby_2/join_association.rb +0 -2
- data/lib/polyamorous/activerecord_4.1_ruby_2/join_dependency.rb +0 -3
- data/lib/polyamorous/activerecord_4.1_ruby_2/make_polyamorous_inner_joins.rb +0 -14
- data/lib/polyamorous/activerecord_4.2_ruby_1.9/join_association.rb +0 -46
- data/lib/polyamorous/activerecord_4.2_ruby_1.9/join_dependency.rb +0 -87
- data/lib/polyamorous/activerecord_4.2_ruby_2/join_association.rb +0 -2
- data/lib/polyamorous/activerecord_4.2_ruby_2/join_dependency.rb +0 -24
- data/spec/blueprints/articles.rb +0 -5
- data/spec/blueprints/comments.rb +0 -5
- data/spec/blueprints/notes.rb +0 -3
- data/spec/blueprints/people.rb +0 -4
- data/spec/blueprints/tags.rb +0 -3
- data/spec/helpers/polyamorous_helper.rb +0 -26
- data/spec/polyamorous/join_association_spec.rb +0 -54
- data/spec/polyamorous/join_dependency_spec.rb +0 -102
- data/spec/polyamorous/join_spec.rb +0 -19
- data/spec/spec_helper.rb +0 -43
- data/spec/support/schema.rb +0 -98
@@ -1,14 +0,0 @@
|
|
1
|
-
module Polyamorous
|
2
|
-
module JoinDependencyExtensions
|
3
|
-
# Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins
|
4
|
-
#
|
5
|
-
def make_polyamorous_inner_joins(parent, child)
|
6
|
-
make_constraints(
|
7
|
-
parent, child, child.tables, child.join_type || Arel::Nodes::InnerJoin
|
8
|
-
)
|
9
|
-
.concat child.children.flat_map { |c|
|
10
|
-
make_polyamorous_inner_joins(child, c)
|
11
|
-
}
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# active_record_4.2_ruby_1.9/join_association.rb
|
2
|
-
module Polyamorous
|
3
|
-
module JoinAssociationExtensions
|
4
|
-
include SwappingReflectionClass
|
5
|
-
def self.included(base)
|
6
|
-
base.class_eval do
|
7
|
-
attr_reader :join_type
|
8
|
-
alias_method_chain :initialize, :polymorphism
|
9
|
-
alias_method_chain :build_constraint, :polymorphism
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize_with_polymorphism(reflection, children,
|
14
|
-
polymorphic_class = nil, join_type = Arel::Nodes::InnerJoin)
|
15
|
-
@join_type = join_type
|
16
|
-
if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
|
17
|
-
swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
|
18
|
-
initialize_without_polymorphism(reflection, children)
|
19
|
-
self.reflection.options[:polymorphic] = true
|
20
|
-
end
|
21
|
-
else
|
22
|
-
initialize_without_polymorphism(reflection, children)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
# Reference https://github.com/rails/rails/commit/9b15db51b78028bfecdb85595624de4b838adbd1
|
27
|
-
def ==(other)
|
28
|
-
base_klass == other.base_klass
|
29
|
-
end
|
30
|
-
|
31
|
-
def build_constraint_with_polymorphism(
|
32
|
-
klass, table, key, foreign_table, foreign_key
|
33
|
-
)
|
34
|
-
if reflection.polymorphic?
|
35
|
-
build_constraint_without_polymorphism(
|
36
|
-
klass, table, key, foreign_table, foreign_key
|
37
|
-
)
|
38
|
-
.and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
|
39
|
-
else
|
40
|
-
build_constraint_without_polymorphism(
|
41
|
-
klass, table, key, foreign_table, foreign_key
|
42
|
-
)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
# active_record_4.2_ruby_1.9/join_dependency.rb
|
2
|
-
require 'polyamorous/activerecord_4.2_ruby_2/join_dependency'
|
3
|
-
|
4
|
-
module Polyamorous
|
5
|
-
module JoinDependencyExtensions
|
6
|
-
def self.included(base)
|
7
|
-
base.extend ClassMethods
|
8
|
-
base.class_eval do
|
9
|
-
class << self
|
10
|
-
alias_method :walk_tree_without_polymorphism, :walk_tree
|
11
|
-
alias_method :walk_tree, :walk_tree_with_polymorphism
|
12
|
-
end
|
13
|
-
|
14
|
-
alias_method :build_without_polymorphism, :build
|
15
|
-
alias_method :build, :build_with_polymorphism
|
16
|
-
|
17
|
-
alias_method :join_constraints_without_polymorphism, :join_constraints
|
18
|
-
alias_method :join_constraints, :join_constraints_with_polymorphism
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Replaces ActiveRecord::Associations::JoinDependency#build
|
23
|
-
#
|
24
|
-
def build_with_polymorphism(associations, base_klass)
|
25
|
-
associations.map do |name, right|
|
26
|
-
if name.is_a? Join
|
27
|
-
reflection = find_reflection base_klass, name.name
|
28
|
-
reflection.check_validity!
|
29
|
-
klass = if reflection.polymorphic?
|
30
|
-
name.klass || base_klass
|
31
|
-
else
|
32
|
-
reflection.klass
|
33
|
-
end
|
34
|
-
JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
|
35
|
-
else
|
36
|
-
reflection = find_reflection base_klass, name
|
37
|
-
reflection.check_validity!
|
38
|
-
if reflection.polymorphic?
|
39
|
-
raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
|
40
|
-
end
|
41
|
-
JoinAssociation.new reflection, build(right, reflection.klass)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Replaces ActiveRecord::Associations::JoinDependency#join_constraints
|
47
|
-
# to call #make_polyamorous_inner_joins instead of #make_inner_joins
|
48
|
-
#
|
49
|
-
def join_constraints_with_polymorphism(outer_joins)
|
50
|
-
joins = join_root.children.flat_map { |child|
|
51
|
-
make_polyamorous_inner_joins join_root, child
|
52
|
-
}
|
53
|
-
joins.concat outer_joins.flat_map { |oj|
|
54
|
-
if join_root.match? oj.join_root
|
55
|
-
walk(join_root, oj.join_root)
|
56
|
-
else
|
57
|
-
oj.join_root.children.flat_map { |child|
|
58
|
-
make_outer_joins(oj.join_root, child)
|
59
|
-
}
|
60
|
-
end
|
61
|
-
}
|
62
|
-
end
|
63
|
-
|
64
|
-
module ClassMethods
|
65
|
-
# Replaces ActiveRecord::Associations::JoinDependency#self.walk_tree
|
66
|
-
#
|
67
|
-
def walk_tree_with_polymorphism(associations, hash)
|
68
|
-
case associations
|
69
|
-
when TreeNode
|
70
|
-
associations.add_to_tree(hash)
|
71
|
-
when Hash
|
72
|
-
associations.each do |k, v|
|
73
|
-
cache =
|
74
|
-
if TreeNode === k
|
75
|
-
k.add_to_tree(hash)
|
76
|
-
else
|
77
|
-
hash[k] ||= {}
|
78
|
-
end
|
79
|
-
walk_tree(v, cache)
|
80
|
-
end
|
81
|
-
else
|
82
|
-
walk_tree_without_polymorphism(associations, hash)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# active_record_4.2_ruby_2/join_dependency.rb
|
2
|
-
require 'polyamorous/activerecord_5.0_ruby_2/join_dependency'
|
3
|
-
|
4
|
-
module Polyamorous
|
5
|
-
module JoinDependencyExtensions
|
6
|
-
# Replaces ActiveRecord::Associations::JoinDependency#join_constraints
|
7
|
-
# to call #make_polyamorous_inner_joins instead of #make_inner_joins.
|
8
|
-
#
|
9
|
-
def join_constraints(outer_joins)
|
10
|
-
joins = join_root.children.flat_map { |child|
|
11
|
-
make_polyamorous_inner_joins join_root, child
|
12
|
-
}
|
13
|
-
joins.concat outer_joins.flat_map { |oj|
|
14
|
-
if join_root.match? oj.join_root
|
15
|
-
walk(join_root, oj.join_root)
|
16
|
-
else
|
17
|
-
oj.join_root.children.flat_map { |child|
|
18
|
-
make_outer_joins(oj.join_root, child)
|
19
|
-
}
|
20
|
-
end
|
21
|
-
}
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/spec/blueprints/articles.rb
DELETED
data/spec/blueprints/comments.rb
DELETED
data/spec/blueprints/notes.rb
DELETED
data/spec/blueprints/people.rb
DELETED
data/spec/blueprints/tags.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module PolyamorousHelper
|
2
|
-
if ActiveRecord::VERSION::STRING >= "4.1"
|
3
|
-
def new_join_association(reflection, children, klass)
|
4
|
-
Polyamorous::JoinAssociation.new reflection, children, klass
|
5
|
-
end
|
6
|
-
else
|
7
|
-
def new_join_association(reflection, join_dependency, parent, klass)
|
8
|
-
Polyamorous::JoinAssociation.new reflection, join_dependency, parent, klass
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
if ActiveRecord::VERSION::STRING >= "5.2"
|
13
|
-
def new_join_dependency(klass, associations = {})
|
14
|
-
alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(klass.connection, klass.table_name, [])
|
15
|
-
Polyamorous::JoinDependency.new klass, klass.arel_table, associations, alias_tracker
|
16
|
-
end
|
17
|
-
else
|
18
|
-
def new_join_dependency(klass, associations = {})
|
19
|
-
Polyamorous::JoinDependency.new klass, associations, []
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def new_join(name, type = Polyamorous::InnerJoin, klass = nil)
|
24
|
-
Polyamorous::Join.new name, type, klass
|
25
|
-
end
|
26
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Polyamorous
|
4
|
-
describe JoinAssociation do
|
5
|
-
|
6
|
-
join_base, join_association_args, polymorphic =
|
7
|
-
if ActiveRecord::VERSION::STRING >= '4.1'
|
8
|
-
[:join_root, 'parent.children', 'reflection.options[:polymorphic]']
|
9
|
-
else
|
10
|
-
[:join_base, 'join_dependency, parent', 'options[:polymorphic]']
|
11
|
-
end
|
12
|
-
|
13
|
-
let(:join_dependency) { new_join_dependency Note, {} }
|
14
|
-
let(:reflection) { Note.reflect_on_association(:notable) }
|
15
|
-
let(:parent) { join_dependency.send(join_base) }
|
16
|
-
let(:join_association) {
|
17
|
-
eval("new_join_association(reflection, #{join_association_args}, Article)")
|
18
|
-
}
|
19
|
-
|
20
|
-
subject {
|
21
|
-
join_dependency.build_join_association_respecting_polymorphism(
|
22
|
-
reflection, parent, Person
|
23
|
-
)
|
24
|
-
}
|
25
|
-
|
26
|
-
it 'respects polymorphism on equality test' do
|
27
|
-
expect(subject).to eq(
|
28
|
-
join_dependency.build_join_association_respecting_polymorphism(
|
29
|
-
reflection, parent, Person
|
30
|
-
)
|
31
|
-
)
|
32
|
-
expect(subject).not_to eq(
|
33
|
-
join_dependency.build_join_association_respecting_polymorphism(
|
34
|
-
reflection, parent, Article
|
35
|
-
)
|
36
|
-
)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'leaves the orginal reflection intact for thread safety' do
|
40
|
-
reflection.instance_variable_set(:@klass, Article)
|
41
|
-
join_association
|
42
|
-
.swapping_reflection_klass(reflection, Person) do |new_reflection|
|
43
|
-
expect(new_reflection.options).not_to equal reflection.options
|
44
|
-
expect(new_reflection.options).not_to have_key(:polymorphic)
|
45
|
-
expect(new_reflection.klass).to eq(Person)
|
46
|
-
expect(reflection.klass).to eq(Article)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'sets the polymorphic option to true after initializing' do
|
51
|
-
expect(join_association.instance_eval(polymorphic)).to be true
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Polyamorous
|
4
|
-
describe JoinDependency do
|
5
|
-
|
6
|
-
method, join_associations, join_base =
|
7
|
-
if ActiveRecord::VERSION::STRING >= '4.1'
|
8
|
-
[:instance_eval, 'join_root.drop(1)', :join_root]
|
9
|
-
else
|
10
|
-
[:send, 'join_associations', :join_base]
|
11
|
-
end
|
12
|
-
|
13
|
-
context 'with symbol joins' do
|
14
|
-
subject { new_join_dependency Person, articles: :comments }
|
15
|
-
|
16
|
-
specify { expect(subject.send(method, join_associations).size)
|
17
|
-
.to eq(2) }
|
18
|
-
specify { expect(subject.send(method, join_associations).map(&:join_type))
|
19
|
-
.to be_all { Polyamorous::InnerJoin } }
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'with has_many :through association' do
|
23
|
-
subject { new_join_dependency Person, :authored_article_comments }
|
24
|
-
|
25
|
-
specify { expect(subject.send(method, join_associations).size)
|
26
|
-
.to eq 1 }
|
27
|
-
specify { expect(subject.send(method, join_associations).first.table_name)
|
28
|
-
.to eq 'comments' }
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'with outer join' do
|
32
|
-
subject { new_join_dependency Person, new_join(:articles, :outer) }
|
33
|
-
|
34
|
-
specify { expect(subject.send(method, join_associations).size)
|
35
|
-
.to eq 1 }
|
36
|
-
specify { expect(subject.send(method, join_associations).first.join_type)
|
37
|
-
.to eq Polyamorous::OuterJoin }
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'with nested outer joins' do
|
41
|
-
subject { new_join_dependency Person,
|
42
|
-
new_join(:articles, :outer) => new_join(:comments, :outer) }
|
43
|
-
|
44
|
-
specify { expect(subject.send(method, join_associations).size)
|
45
|
-
.to eq 2 }
|
46
|
-
specify { expect(subject.send(method, join_associations).map(&:join_type))
|
47
|
-
.to eq [Polyamorous::OuterJoin, Polyamorous::OuterJoin] }
|
48
|
-
specify { expect(subject.send(method, join_associations).map(&:join_type))
|
49
|
-
.to be_all { Polyamorous::OuterJoin } }
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'with polymorphic belongs_to join' do
|
53
|
-
subject { new_join_dependency Note, new_join(:notable, :inner, Person) }
|
54
|
-
|
55
|
-
specify { expect(subject.send(method, join_associations).size)
|
56
|
-
.to eq 1 }
|
57
|
-
specify { expect(subject.send(method, join_associations).first.join_type)
|
58
|
-
.to eq Polyamorous::InnerJoin }
|
59
|
-
specify { expect(subject.send(method, join_associations).first.table_name)
|
60
|
-
.to eq 'people' }
|
61
|
-
|
62
|
-
it 'finds a join association respecting polymorphism' do
|
63
|
-
parent = subject.send(join_base)
|
64
|
-
reflection = Note.reflect_on_association(:notable)
|
65
|
-
|
66
|
-
expect(subject.find_join_association_respecting_polymorphism(
|
67
|
-
reflection, parent, Person))
|
68
|
-
.to eq subject.send(method, join_associations).first
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
context 'with polymorphic belongs_to join and nested symbol join' do
|
73
|
-
subject { new_join_dependency Note,
|
74
|
-
new_join(:notable, :inner, Person) => :comments }
|
75
|
-
|
76
|
-
specify { expect(subject.send(method, join_associations).size)
|
77
|
-
.to eq 2 }
|
78
|
-
specify { expect(subject.send(method, join_associations).map(&:join_type))
|
79
|
-
.to be_all { Polyamorous::InnerJoin } }
|
80
|
-
specify { expect(subject.send(method, join_associations).first.table_name)
|
81
|
-
.to eq 'people' }
|
82
|
-
specify { expect(subject.send(method, join_associations)[1].table_name)
|
83
|
-
.to eq 'comments' }
|
84
|
-
end
|
85
|
-
|
86
|
-
context '#left_outer_join in Rails 5 overrides join type specified',
|
87
|
-
if: ActiveRecord::VERSION::MAJOR >= 5 && ActiveRecord::VERSION::MINOR < 2 do
|
88
|
-
|
89
|
-
let(:join_type_class) do
|
90
|
-
new_join_dependency(
|
91
|
-
Person,
|
92
|
-
new_join(:articles)
|
93
|
-
).join_constraints(
|
94
|
-
[],
|
95
|
-
Arel::Nodes::OuterJoin
|
96
|
-
).first.joins.map(&:class)
|
97
|
-
end
|
98
|
-
|
99
|
-
specify { expect(join_type_class).to eq [Arel::Nodes::OuterJoin] }
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Polyamorous
|
4
|
-
describe Join do
|
5
|
-
it 'is a tree node' do
|
6
|
-
join = new_join(:articles, :outer)
|
7
|
-
expect(join).to be_kind_of(TreeNode)
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'can be added to a tree' do
|
11
|
-
join = new_join(:articles, :outer)
|
12
|
-
|
13
|
-
tree_hash = {}
|
14
|
-
join.add_to_tree(tree_hash)
|
15
|
-
|
16
|
-
expect(tree_hash[join]).to be {}
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'machinist/active_record'
|
2
|
-
require 'sham'
|
3
|
-
require 'faker'
|
4
|
-
require 'polyamorous'
|
5
|
-
|
6
|
-
Time.zone = 'Eastern Time (US & Canada)'
|
7
|
-
|
8
|
-
Dir[File.expand_path('../{helpers,support,blueprints}/**/*.rb', __FILE__)]
|
9
|
-
.each do |f|
|
10
|
-
require f
|
11
|
-
end
|
12
|
-
|
13
|
-
Sham.define do
|
14
|
-
name { Faker::Name.name }
|
15
|
-
title { Faker::Lorem.sentence }
|
16
|
-
body { Faker::Lorem.paragraph }
|
17
|
-
salary { |index| 30000 + (index * 1000) }
|
18
|
-
tag_name { Faker::Lorem.words(3).join(' ') }
|
19
|
-
note { Faker::Lorem.words(7).join(' ') }
|
20
|
-
end
|
21
|
-
|
22
|
-
RSpec.configure do |config|
|
23
|
-
config.before(:suite) do
|
24
|
-
message = "Running Polyamorous specs with #{
|
25
|
-
ActiveRecord::Base.connection.adapter_name
|
26
|
-
}, Active Record #{::ActiveRecord::VERSION::STRING}, Arel #{Arel::VERSION
|
27
|
-
} and Ruby #{RUBY_VERSION}"
|
28
|
-
line = '=' * message.length
|
29
|
-
puts line, message, line
|
30
|
-
Schema.create
|
31
|
-
end
|
32
|
-
config.before(:all) { Sham.reset(:before_all) }
|
33
|
-
config.before(:each) { Sham.reset(:before_each) }
|
34
|
-
|
35
|
-
config.include PolyamorousHelper
|
36
|
-
end
|
37
|
-
|
38
|
-
RSpec::Matchers.define :be_like do |expected|
|
39
|
-
match do |actual|
|
40
|
-
actual.gsub(/^\s+|\s+$/, '').gsub(/\s+/, ' ').strip ==
|
41
|
-
expected.gsub(/^\s+|\s+$/, '').gsub(/\s+/, ' ').strip
|
42
|
-
end
|
43
|
-
end
|