polyamorous 1.2.0 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +34 -30
  3. data/README.md +13 -10
  4. data/lib/polyamorous/activerecord_4.1_ruby_1.9/join_dependency.rb +1 -1
  5. data/lib/polyamorous/activerecord_4.1_ruby_2/join_association.rb +1 -1
  6. data/lib/polyamorous/activerecord_4.1_ruby_2/join_dependency.rb +1 -1
  7. data/lib/polyamorous/activerecord_4.1_ruby_2/{make_joins.rb → make_polyamorous_inner_joins.rb} +5 -2
  8. data/lib/polyamorous/activerecord_4.2_ruby_1.9/join_dependency.rb +16 -23
  9. data/lib/polyamorous/activerecord_4.2_ruby_2/join_association.rb +1 -36
  10. data/lib/polyamorous/activerecord_4.2_ruby_2/join_dependency.rb +5 -86
  11. data/lib/polyamorous/activerecord_5.0_ruby_2/join_association.rb +2 -0
  12. data/lib/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb +2 -0
  13. data/lib/polyamorous/activerecord_5.1_ruby_2/join_association.rb +39 -0
  14. data/lib/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb +130 -0
  15. data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +39 -0
  16. data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +130 -0
  17. data/lib/polyamorous/version.rb +1 -1
  18. data/lib/polyamorous.rb +2 -9
  19. data/polyamorous.gemspec +2 -2
  20. data/spec/helpers/polyamorous_helper.rb +9 -3
  21. data/spec/polyamorous/join_association_spec.rb +47 -4
  22. data/spec/polyamorous/join_dependency_spec.rb +95 -4
  23. data/spec/polyamorous/join_spec.rb +1 -1
  24. metadata +14 -16
  25. data/spec/support/shared_examples/join_association_3_and_4.0.rb +0 -42
  26. data/spec/support/shared_examples/join_association_4.1.rb +0 -42
  27. data/spec/support/shared_examples/join_dependency_3_and_4.0.rb +0 -65
  28. data/spec/support/shared_examples/join_dependency_4.1.rb +0 -65
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a754ac3545728f4de5d4d5e4f75687991f7b41ca
4
- data.tar.gz: c2a55008f158f99fd534e66b2306e045271edf1d
3
+ metadata.gz: c99b340d1137da69048738077239bf10471388fe
4
+ data.tar.gz: 289568abe8acfc3dd93b8c3fb45f7a6910fd1752
5
5
  SHA512:
6
- metadata.gz: 1ae3f57016adf1c30563485ae3ae7155aa3e95c880241231e346930de0ab16e1a75082d79563ba2850f2f2513ab7f7a92dd78a5d14e88c19e0aebaf551cdf422
7
- data.tar.gz: e0f9296bbbe67e09691d67e5d70b4a0809e71db9ae9a79fcd6bfed483834cf9dae15bf733ed22f645009a7cca66d4f4f79a7fd6aef3952a28fd75d4259e41f06
6
+ metadata.gz: 0f035d8d3d7ec83992e5eb63f2bd608a7131c1104ad86b5320d7eb953d7e6f8159bf4458636cb03ca0506e18c1bba83f996ede2772bbd11671eec38b251314b0
7
+ data.tar.gz: 7186a137a3299ce00fdf66526e5a71763cbd99737811e48f0285b2dd2ea1b1bc0952fbf1cb750c24e26393708071e3f753a794022261871e88d1a6958edd0fe6
data/.travis.yml CHANGED
@@ -1,53 +1,57 @@
1
1
  language: ruby
2
2
 
3
3
  sudo: false
4
+ cache: bundler
4
5
 
5
6
  before_install:
6
7
  - travis_retry gem install bundler
7
8
 
8
9
  rvm:
9
- - 2.2.1
10
- - 2.1
11
- - 2.0
12
- - 1.9
10
+ - 2.5.0
11
+ - 2.4.3
12
+ - 2.3.6
13
+ - 2.2.9
13
14
 
14
15
  env:
15
16
  - RAILS=4-2-stable AREL=6-0-stable DB=sqlite
16
17
  - RAILS=4-2-stable AREL=6-0-stable DB=mysql
17
18
  - RAILS=4-2-stable AREL=6-0-stable DB=postgres
19
+ - RAILS=5-0-stable AREL=7-0-stable DB=sqlite
20
+ - RAILS=5-0-stable AREL=7-0-stable DB=mysql
21
+ - RAILS=5-0-stable AREL=7-0-stable DB=postgres
22
+ - RAILS=5-1-stable AREL=8-0-stable DB=sqlite
23
+ - RAILS=5-1-stable AREL=8-0-stable DB=mysql
24
+ - RAILS=5-1-stable AREL=8-0-stable DB=postgres
18
25
 
19
- - RAILS=4-1-stable AREL=5-0-stable DB=sqlite
20
- - RAILS=4-1-stable AREL=5-0-stable DB=mysql
21
- - RAILS=4-1-stable AREL=5-0-stable DB=postgres
22
-
23
- - RAILS=4-0-stable AREL=4-0-stable DB=sqlite
24
- - RAILS=4-0-stable AREL=4-0-stable DB=mysql
25
- - RAILS=4-0-stable AREL=4-0-stable DB=postgres
26
-
27
- - RAILS=3-2-stable AREL=3-0-stable DB=sqlite
28
- - RAILS=3-2-stable AREL=3-0-stable DB=mysql
29
- - RAILS=3-2-stable AREL=3-0-stable DB=postgres
26
+ matrix:
27
+ include:
28
+ - rvm: 2.5.0
29
+ env: RAILS=master DB=sqlite3
30
+ - rvm: 2.5.0
31
+ env: RAILS=master DB=mysql
32
+ - rvm: 2.5.0
33
+ env: RAILS=master DB=postgres
30
34
 
31
- - RAILS=3-1-stable AREL=2-2-stable DB=sqlite
32
- - RAILS=3-1-stable AREL=2-2-stable DB=mysql
33
- - RAILS=3-1-stable AREL=2-2-stable DB=postgres
35
+ - rvm: 2.4.3
36
+ env: RAILS=master DB=sqlite3
37
+ - rvm: 2.4.3
38
+ env: RAILS=master DB=mysql
39
+ - rvm: 2.4.3
40
+ env: RAILS=master DB=postgres
34
41
 
35
- - RAILS=3-0-stable AREL=2-0-stable DB=sqlite
36
- - RAILS=3-0-stable AREL=2-0-stable DB=mysql
37
- - RAILS=3-0-stable AREL=2-0-stable DB=postgres
42
+ - rvm: 2.3.6
43
+ env: RAILS=master DB=sqlite3
44
+ - rvm: 2.3.6
45
+ env: RAILS=master DB=mysql
46
+ - rvm: 2.3.6
47
+ env: RAILS=master DB=postgres
38
48
 
39
- matrix:
40
- include:
41
- - rvm: 2.2.1
49
+ - rvm: 2.2.9
42
50
  env: RAILS=master DB=sqlite3
43
- - rvm: 2.2.1
51
+ - rvm: 2.2.9
44
52
  env: RAILS=master DB=mysql
45
- - rvm: 2.2.1
53
+ - rvm: 2.2.9
46
54
  env: RAILS=master DB=postgres
47
- allow_failures:
48
- - env: RAILS=master DB=sqlite3
49
- - env: RAILS=master DB=mysql
50
- - env: RAILS=master DB=postgres
51
55
 
52
56
  before_script:
53
57
  - mysql -e 'create database ransack collate utf8_general_ci;'
data/README.md CHANGED
@@ -1,18 +1,21 @@
1
1
  # Polyamorous
2
+ [![Build Status](https://travis-ci.org/activerecord-hackery/polyamorous.svg?branch=master)](https://travis-ci.org/activerecord-hackery/polyamorous)
3
+ [![Gem Version](https://badge.fury.io/rb/polyamorous.svg)](https://badge.fury.io/rb/polyamorous)
4
+ [![Code Climate](https://codeclimate.com/github/activerecord-hackery/polyamorous/badges/gpa.svg)](https://codeclimate.com/github/activerecord-hackery/polyamorous)
2
5
 
3
- [![Build Status](https://travis-ci.org/activerecord-hackery/polyamorous.svg)]
4
- (https://travis-ci.org/activerecord-hackery/polyamorous)
5
- [![Gem Version](https://badge.fury.io/rb/polyamorous.svg)]
6
- (http://badge.fury.io/rb/polyamorous)
7
-
8
- Polyamorous is an extraction from MetaSearch 1.1.x, Ransack, and Squeel by
6
+ Polyamorous is an extraction of shared code from the
7
+ [Active Record Hackery](https://github.com/activerecord-hackery) gems
8
+ [Ransack](https://github.com/activerecord-hackery/ransack),
9
+ [Squeel](https://github.com/activerecord-hackery/squeel) and
10
+ [MetaSearch](https://github.com/activerecord-hackery/meta_search) by
9
11
  [Ernie Miller](http://twitter.com/erniemiller) and maintained by
10
12
  [Ryan Bigg](http://twitter.com/ryanbigg),
11
13
  [Xiang Li](http://bigxiang.github.io),
12
- [Jon Atack](http://twitter.com/jonatack) and a great group of
14
+ [Jon Atack](http://twitter.com/jonatack),
15
+ [Sean Carroll](https://github.com/seanfcarroll) and a great little group of
13
16
  [contributors]
14
17
  (https://github.com/activerecord-hackery/polyamorous/graphs/contributors).
15
18
 
16
- ## Copyright
17
-
18
- Copyright © 2011-2015 [Ernie Miller](http://twitter.com/erniemiller)
19
+ It is an internal library for extending various versions of Active Record with
20
+ polymorphism. There is no public API, so it's `:nodoc:`. Move along. Nothing to
21
+ see here.
@@ -1,4 +1,4 @@
1
1
  # active_record_4.1_ruby_1.9/join_dependency.rb
2
2
  require 'polyamorous/activerecord_4.2_ruby_2/join_dependency'
3
3
  require 'polyamorous/activerecord_4.2_ruby_1.9/join_dependency'
4
- require 'polyamorous/activerecord_4.1_ruby_2/make_joins'
4
+ require 'polyamorous/activerecord_4.1_ruby_2/make_polyamorous_inner_joins'
@@ -1,2 +1,2 @@
1
1
  # active_record_4.1_ruby_2/join_association.rb
2
- require 'polyamorous/activerecord_4.2_ruby_2/join_association'
2
+ require 'polyamorous/activerecord_5.0_ruby_2/join_association'
@@ -1,3 +1,3 @@
1
1
  # active_record_4.1_ruby_2/join_dependency.rb
2
2
  require 'polyamorous/activerecord_4.2_ruby_2/join_dependency'
3
- require 'polyamorous/activerecord_4.1_ruby_2/make_joins'
3
+ require 'polyamorous/activerecord_4.1_ruby_2/make_polyamorous_inner_joins'
@@ -1,11 +1,14 @@
1
1
  module Polyamorous
2
2
  module JoinDependencyExtensions
3
3
  # Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins
4
- def make_joins(parent, child)
4
+ #
5
+ def make_polyamorous_inner_joins(parent, child)
5
6
  make_constraints(
6
7
  parent, child, child.tables, child.join_type || Arel::Nodes::InnerJoin
7
8
  )
8
- .concat child.children.flat_map { |c| make_inner_joins(child, c) }
9
+ .concat child.children.flat_map { |c|
10
+ make_polyamorous_inner_joins(child, c)
11
+ }
9
12
  end
10
13
  end
11
14
  end
@@ -20,26 +20,18 @@ module Polyamorous
20
20
  end
21
21
 
22
22
  # Replaces ActiveRecord::Associations::JoinDependency#build
23
+ #
23
24
  def build_with_polymorphism(associations, base_klass)
24
25
  associations.map do |name, right|
25
26
  if name.is_a? Join
26
27
  reflection = find_reflection base_klass, name.name
27
28
  reflection.check_validity!
28
- if reflection.polymorphic?
29
- JoinAssociation.new(
30
- reflection,
31
- build(right, name.klass || base_klass),
32
- name.klass,
33
- name.type
34
- )
29
+ klass = if reflection.polymorphic?
30
+ name.klass || base_klass
35
31
  else
36
- JoinAssociation.new(
37
- reflection,
38
- build(right, reflection.klass),
39
- name.klass,
40
- name.type
41
- )
32
+ reflection.klass
42
33
  end
34
+ JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
43
35
  else
44
36
  reflection = find_reflection base_klass, name
45
37
  reflection.check_validity!
@@ -52,10 +44,11 @@ module Polyamorous
52
44
  end
53
45
 
54
46
  # Replaces ActiveRecord::Associations::JoinDependency#join_constraints
55
- # to call #make_joins instead of #make_inner_joins.
47
+ # to call #make_polyamorous_inner_joins instead of #make_inner_joins
48
+ #
56
49
  def join_constraints_with_polymorphism(outer_joins)
57
50
  joins = join_root.children.flat_map { |child|
58
- make_joins(join_root, child)
51
+ make_polyamorous_inner_joins join_root, child
59
52
  }
60
53
  joins.concat outer_joins.flat_map { |oj|
61
54
  if join_root.match? oj.join_root
@@ -69,7 +62,8 @@ module Polyamorous
69
62
  end
70
63
 
71
64
  module ClassMethods
72
- # Replaces ActiveRecord::Associations::JoinDependency#self.walk_tree
65
+ # Replaces ActiveRecord::Associations::JoinDependency#self.walk_tree
66
+ #
73
67
  def walk_tree_with_polymorphism(associations, hash)
74
68
  case associations
75
69
  when TreeNode
@@ -77,14 +71,13 @@ module Polyamorous
77
71
  when Hash
78
72
  associations.each do |k, v|
79
73
  cache =
80
- case k
81
- when TreeNode
82
- k.add_to_tree(hash)
83
- else
84
- hash[k] ||= {}
85
- end
74
+ if TreeNode === k
75
+ k.add_to_tree(hash)
76
+ else
77
+ hash[k] ||= {}
78
+ end
86
79
  walk_tree(v, cache)
87
- end
80
+ end
88
81
  else
89
82
  walk_tree_without_polymorphism(associations, hash)
90
83
  end
@@ -1,37 +1,2 @@
1
1
  # active_record_4.2_ruby_2/join_association.rb
2
- module Polyamorous
3
- module JoinAssociationExtensions
4
- include SwappingReflectionClass
5
- def self.prepended(base)
6
- base.class_eval { attr_reader :join_type }
7
- end
8
-
9
- def initialize(reflection, children, polymorphic_class = nil,
10
- join_type = Arel::Nodes::InnerJoin)
11
- @join_type = join_type
12
- if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
13
- swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
14
- super(reflection, children)
15
- self.reflection.options[:polymorphic] = true
16
- end
17
- else
18
- super(reflection, children)
19
- end
20
- end
21
-
22
- # Reference https://github.com/rails/rails/commit/9b15db51b78028bfecdb85595624de4b838adbd1
23
- # NOTE Not sure we still need it?
24
- def ==(other)
25
- base_klass == other.base_klass
26
- end
27
-
28
- def build_constraint(klass, table, key, foreign_table, foreign_key)
29
- if reflection.polymorphic?
30
- super(klass, table, key, foreign_table, foreign_key)
31
- .and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
32
- else
33
- super(klass, table, key, foreign_table, foreign_key)
34
- end
35
- end
36
- end
37
- end
2
+ require 'polyamorous/activerecord_5.0_ruby_2/join_association'
@@ -1,61 +1,14 @@
1
1
  # active_record_4.2_ruby_2/join_dependency.rb
2
+ require 'polyamorous/activerecord_5.0_ruby_2/join_dependency'
3
+
2
4
  module Polyamorous
3
5
  module JoinDependencyExtensions
4
- # Replaces ActiveRecord::Associations::JoinDependency#build
5
- def build(associations, base_klass)
6
- associations.map do |name, right|
7
- if name.is_a? Join
8
- reflection = find_reflection base_klass, name.name
9
- reflection.check_validity!
10
- if reflection.polymorphic?
11
- JoinAssociation.new(
12
- reflection,
13
- build(right, name.klass || base_klass),
14
- name.klass,
15
- name.type
16
- )
17
- else
18
- JoinAssociation.new(
19
- reflection,
20
- build(right, reflection.klass),
21
- name.klass,
22
- name.type
23
- )
24
- end
25
- else
26
- reflection = find_reflection base_klass, name
27
- reflection.check_validity!
28
- if reflection.polymorphic?
29
- raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
30
- end
31
- JoinAssociation.new reflection, build(right, reflection.klass)
32
- end
33
- end
34
- end
35
-
36
- def find_join_association_respecting_polymorphism(reflection, parent, klass)
37
- if association = parent.children.find { |j| j.reflection == reflection }
38
- unless reflection.polymorphic?
39
- association
40
- else
41
- association if association.base_klass == klass
42
- end
43
- end
44
- end
45
-
46
- def build_join_association_respecting_polymorphism(reflection, parent, klass)
47
- if reflection.polymorphic? && klass
48
- JoinAssociation.new(reflection, self, klass)
49
- else
50
- JoinAssociation.new(reflection, self)
51
- end
52
- end
53
-
54
6
  # Replaces ActiveRecord::Associations::JoinDependency#join_constraints
55
- # to call #make_joins instead of #make_inner_joins.
7
+ # to call #make_polyamorous_inner_joins instead of #make_inner_joins.
8
+ #
56
9
  def join_constraints(outer_joins)
57
10
  joins = join_root.children.flat_map { |child|
58
- make_joins(join_root, child)
11
+ make_polyamorous_inner_joins join_root, child
59
12
  }
60
13
  joins.concat outer_joins.flat_map { |oj|
61
14
  if join_root.match? oj.join_root
@@ -67,39 +20,5 @@ module Polyamorous
67
20
  end
68
21
  }
69
22
  end
70
-
71
- # Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins
72
- def make_joins(parent, child)
73
- [
74
- make_constraints(
75
- parent, child, child.tables, child.join_type || Arel::Nodes::InnerJoin
76
- )
77
- ] + child.children.flat_map { |c| make_inner_joins(child, c) }
78
- end
79
-
80
- private :make_joins
81
-
82
- module ClassMethods
83
- # Prepended before ActiveRecord::Associations::JoinDependency#self.walk_tree
84
- def walk_tree(associations, hash)
85
- case associations
86
- when TreeNode
87
- associations.add_to_tree(hash)
88
- when Hash
89
- associations.each do |k, v|
90
- cache =
91
- case k
92
- when TreeNode
93
- k.add_to_tree(hash)
94
- else
95
- hash[k] ||= {}
96
- end
97
- walk_tree(v, cache)
98
- end
99
- else
100
- super(associations, hash)
101
- end
102
- end
103
- end
104
23
  end
105
24
  end
@@ -0,0 +1,2 @@
1
+ # active_record_5.0_ruby_2/join_association.rb
2
+ require 'polyamorous/activerecord_5.1_ruby_2/join_association'
@@ -0,0 +1,2 @@
1
+ # active_record_5.0_ruby_2/join_dependency.rb
2
+ require 'polyamorous/activerecord_5.1_ruby_2/join_dependency'
@@ -0,0 +1,39 @@
1
+ # active_record_5.1_ruby_2/join_association.rb
2
+
3
+ module Polyamorous
4
+ module JoinAssociationExtensions
5
+ include SwappingReflectionClass
6
+ def self.prepended(base)
7
+ base.class_eval { attr_reader :join_type }
8
+ end
9
+
10
+ def initialize(reflection, children, polymorphic_class = nil,
11
+ join_type = Arel::Nodes::InnerJoin)
12
+ @join_type = join_type
13
+ if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
14
+ swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
15
+ super(reflection, children)
16
+ self.reflection.options[:polymorphic] = true
17
+ end
18
+ else
19
+ super(reflection, children)
20
+ end
21
+ end
22
+
23
+ # Reference: https://github.com/rails/rails/commit/9b15db5
24
+ # NOTE: Not sure we still need it?
25
+ #
26
+ def ==(other)
27
+ base_klass == other.base_klass
28
+ end
29
+
30
+ def build_constraint(klass, table, key, foreign_table, foreign_key)
31
+ if reflection.polymorphic?
32
+ super(klass, table, key, foreign_table, foreign_key)
33
+ .and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
34
+ else
35
+ super(klass, table, key, foreign_table, foreign_key)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,130 @@
1
+ # active_record_5.1_ruby_2/join_dependency.rb
2
+
3
+ module Polyamorous
4
+ module JoinDependencyExtensions
5
+ # Replaces ActiveRecord::Associations::JoinDependency#build
6
+ #
7
+ def build(associations, base_klass)
8
+ associations.map do |name, right|
9
+ if name.is_a? Join
10
+ reflection = find_reflection base_klass, name.name
11
+ reflection.check_validity!
12
+ reflection.check_eager_loadable! if ActiveRecord::VERSION::MAJOR >= 5
13
+
14
+ klass = if reflection.polymorphic?
15
+ name.klass || base_klass
16
+ else
17
+ reflection.klass
18
+ end
19
+ JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
20
+ else
21
+ reflection = find_reflection base_klass, name
22
+ reflection.check_validity!
23
+ reflection.check_eager_loadable! if ActiveRecord::VERSION::MAJOR >= 5
24
+
25
+ if reflection.polymorphic?
26
+ raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
27
+ end
28
+ JoinAssociation.new reflection, build(right, reflection.klass)
29
+ end
30
+ end
31
+ end
32
+
33
+ def find_join_association_respecting_polymorphism(reflection, parent, klass)
34
+ if association = parent.children.find { |j| j.reflection == reflection }
35
+ unless reflection.polymorphic?
36
+ association
37
+ else
38
+ association if association.base_klass == klass
39
+ end
40
+ end
41
+ end
42
+
43
+ def build_join_association_respecting_polymorphism(reflection, parent, klass)
44
+ if reflection.polymorphic? && klass
45
+ JoinAssociation.new(reflection, self, klass)
46
+ else
47
+ JoinAssociation.new(reflection, self)
48
+ end
49
+ end
50
+
51
+ # Replaces ActiveRecord::Associations::JoinDependency#join_constraints
52
+ #
53
+ # This internal method was changed in Rails 5.0 by commit
54
+ # https://github.com/rails/rails/commit/e038975 which added
55
+ # left_outer_joins (see #make_polyamorous_left_outer_joins below) and added
56
+ # passing an additional argument, `join_type`, to #join_constraints.
57
+ #
58
+ def join_constraints(outer_joins, join_type)
59
+ joins = join_root.children.flat_map { |child|
60
+ if join_type == Arel::Nodes::OuterJoin
61
+ make_polyamorous_left_outer_joins join_root, child
62
+ else
63
+ make_polyamorous_inner_joins join_root, child
64
+ end
65
+ }
66
+
67
+ joins.concat outer_joins.flat_map { |oj|
68
+ if join_root.match? oj.join_root
69
+ walk(join_root, oj.join_root)
70
+ else
71
+ oj.join_root.children.flat_map { |child|
72
+ make_outer_joins(oj.join_root, child)
73
+ }
74
+ end
75
+ }
76
+ end
77
+
78
+ # Replaces ActiveRecord::Associations::JoinDependency#make_left_outer_joins,
79
+ # a new method that was added in Rails 5.0 with the following commit:
80
+ # https://github.com/rails/rails/commit/e038975
81
+ #
82
+ def make_polyamorous_left_outer_joins(parent, child)
83
+ tables = child.tables
84
+ join_type = Arel::Nodes::OuterJoin
85
+ info = make_constraints parent, child, tables, join_type
86
+
87
+ [info] + child.children.flat_map { |c|
88
+ make_polyamorous_left_outer_joins(child, c)
89
+ }
90
+ end
91
+
92
+ # Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins
93
+ #
94
+ def make_polyamorous_inner_joins(parent, child)
95
+ tables = child.tables
96
+ join_type = child.join_type || Arel::Nodes::InnerJoin
97
+ info = make_constraints parent, child, tables, join_type
98
+
99
+ [info] + child.children.flat_map { |c|
100
+ make_polyamorous_inner_joins(child, c)
101
+ }
102
+ end
103
+
104
+ private :make_polyamorous_inner_joins, :make_polyamorous_left_outer_joins
105
+
106
+ module ClassMethods
107
+ # Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
108
+ #
109
+ def walk_tree(associations, hash)
110
+ case associations
111
+ when TreeNode
112
+ associations.add_to_tree(hash)
113
+ when Hash
114
+ associations.each do |k, v|
115
+ cache =
116
+ if TreeNode === k
117
+ k.add_to_tree(hash)
118
+ else
119
+ hash[k] ||= {}
120
+ end
121
+ walk_tree(v, cache)
122
+ end
123
+ else
124
+ super(associations, hash)
125
+ end
126
+ end
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,39 @@
1
+ # active_record_5.2_ruby_2/join_association.rb
2
+
3
+ module Polyamorous
4
+ module JoinAssociationExtensions
5
+ include SwappingReflectionClass
6
+ def self.prepended(base)
7
+ base.class_eval { attr_reader :join_type }
8
+ end
9
+
10
+ def initialize(reflection, children, alias_tracker, polymorphic_class = nil,
11
+ join_type = Arel::Nodes::InnerJoin)
12
+ @join_type = join_type
13
+ if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
14
+ swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
15
+ super(reflection, children, alias_tracker)
16
+ self.reflection.options[:polymorphic] = true
17
+ end
18
+ else
19
+ super(reflection, children, alias_tracker)
20
+ end
21
+ end
22
+
23
+ # Reference: https://github.com/rails/rails/commit/9b15db5
24
+ # NOTE: Not sure we still need it?
25
+ #
26
+ def ==(other)
27
+ base_klass == other.base_klass
28
+ end
29
+
30
+ def build_constraint(klass, table, key, foreign_table, foreign_key)
31
+ if reflection.polymorphic?
32
+ super(klass, table, key, foreign_table, foreign_key)
33
+ .and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
34
+ else
35
+ super(klass, table, key, foreign_table, foreign_key)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,130 @@
1
+ # active_record_5.2_ruby_2/join_dependency.rb
2
+
3
+ module Polyamorous
4
+ module JoinDependencyExtensions
5
+ # Replaces ActiveRecord::Associations::JoinDependency#build
6
+ #
7
+ def build(associations, base_klass)
8
+ associations.map do |name, right|
9
+ if name.is_a? Join
10
+ reflection = find_reflection base_klass, name.name
11
+ reflection.check_validity!
12
+ reflection.check_eager_loadable! if ActiveRecord::VERSION::MAJOR >= 5
13
+
14
+ klass = if reflection.polymorphic?
15
+ name.klass || base_klass
16
+ else
17
+ reflection.klass
18
+ end
19
+ JoinAssociation.new(reflection, build(right, klass), alias_tracker, name.klass, name.type)
20
+ else
21
+ reflection = find_reflection base_klass, name
22
+ reflection.check_validity!
23
+ reflection.check_eager_loadable! if ActiveRecord::VERSION::MAJOR >= 5
24
+
25
+ if reflection.polymorphic?
26
+ raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
27
+ end
28
+ JoinAssociation.new(reflection, build(right, reflection.klass), alias_tracker)
29
+ end
30
+ end
31
+ end
32
+
33
+ def find_join_association_respecting_polymorphism(reflection, parent, klass)
34
+ if association = parent.children.find { |j| j.reflection == reflection }
35
+ unless reflection.polymorphic?
36
+ association
37
+ else
38
+ association if association.base_klass == klass
39
+ end
40
+ end
41
+ end
42
+
43
+ def build_join_association_respecting_polymorphism(reflection, parent, klass)
44
+ if reflection.polymorphic? && klass
45
+ JoinAssociation.new(reflection, self, alias_tracker, klass)
46
+ else
47
+ JoinAssociation.new(reflection, self, alias_tracker)
48
+ end
49
+ end
50
+
51
+ # Replaces ActiveRecord::Associations::JoinDependency#join_constraints
52
+ #
53
+ # This internal method was changed in Rails 5.0 by commit
54
+ # https://github.com/rails/rails/commit/e038975 which added
55
+ # left_outer_joins (see #make_polyamorous_left_outer_joins below) and added
56
+ # passing an additional argument, `join_type`, to #join_constraints.
57
+ #
58
+ def join_constraints(outer_joins, join_type)
59
+ joins = join_root.children.flat_map { |child|
60
+ if join_type == Arel::Nodes::OuterJoin
61
+ make_polyamorous_left_outer_joins join_root, child
62
+ else
63
+ make_polyamorous_inner_joins join_root, child
64
+ end
65
+ }
66
+
67
+ joins.concat outer_joins.flat_map { |oj|
68
+ if join_root.match? oj.join_root
69
+ walk(join_root, oj.join_root)
70
+ else
71
+ oj.join_root.children.flat_map { |child|
72
+ make_outer_joins(oj.join_root, child)
73
+ }
74
+ end
75
+ }
76
+ end
77
+
78
+ # Replaces ActiveRecord::Associations::JoinDependency#make_left_outer_joins,
79
+ # a new method that was added in Rails 5.0 with the following commit:
80
+ # https://github.com/rails/rails/commit/e038975
81
+ #
82
+ def make_polyamorous_left_outer_joins(parent, child)
83
+ tables = child.tables
84
+ join_type = Arel::Nodes::OuterJoin
85
+ info = make_constraints parent, child, tables, join_type
86
+
87
+ info + child.children.flat_map { |c|
88
+ make_polyamorous_left_outer_joins(child, c)
89
+ }
90
+ end
91
+
92
+ # Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins
93
+ #
94
+ def make_polyamorous_inner_joins(parent, child)
95
+ tables = child.tables
96
+ join_type = child.join_type || Arel::Nodes::InnerJoin
97
+ info = make_constraints parent, child, tables, join_type
98
+
99
+ info + child.children.flat_map { |c|
100
+ make_polyamorous_inner_joins(child, c)
101
+ }
102
+ end
103
+
104
+ private :make_polyamorous_inner_joins, :make_polyamorous_left_outer_joins
105
+
106
+ module ClassMethods
107
+ # Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
108
+ #
109
+ def walk_tree(associations, hash)
110
+ case associations
111
+ when TreeNode
112
+ associations.add_to_tree(hash)
113
+ when Hash
114
+ associations.each do |k, v|
115
+ cache =
116
+ if TreeNode === k
117
+ k.add_to_tree(hash)
118
+ else
119
+ hash[k] ||= {}
120
+ end
121
+ walk_tree(v, cache)
122
+ end
123
+ else
124
+ super(associations, hash)
125
+ end
126
+ end
127
+ end
128
+
129
+ end
130
+ end
@@ -1,3 +1,3 @@
1
1
  module Polyamorous
2
- VERSION = '1.2.0'
2
+ VERSION = '1.3.3'
3
3
  end
data/lib/polyamorous.rb CHANGED
@@ -25,15 +25,8 @@ if defined?(::ActiveRecord)
25
25
  require 'polyamorous/join'
26
26
  require 'polyamorous/swapping_reflection_class'
27
27
 
28
- ar_version =
29
- case ::ActiveRecord::VERSION::STRING[0,3]
30
- when '4.2', '5.0'
31
- '4.2'
32
- when '4.1'
33
- '4.1'
34
- else
35
- '3_and_4.0'
36
- end
28
+ ar_version = ::ActiveRecord::VERSION::STRING[0,3]
29
+ ar_version = '3_and_4.0' if ar_version < '4.1'
37
30
 
38
31
  method, ruby_version =
39
32
  if RUBY_VERSION >= '2.0' && ar_version >= '4.1'
data/polyamorous.gemspec CHANGED
@@ -21,9 +21,9 @@ Gem::Specification.new do |s|
21
21
  s.rubyforge_project = "polyamorous"
22
22
 
23
23
  s.add_dependency 'activerecord', '>= 3.0'
24
- s.add_development_dependency 'rspec', '~> 2.14.0'
24
+ s.add_development_dependency 'rspec', '~> 3'
25
25
  s.add_development_dependency 'machinist', '~> 1.0.6'
26
- s.add_development_dependency 'faker', '~> 0.9.5'
26
+ s.add_development_dependency 'faker', '~> 1.6.5'
27
27
  s.add_development_dependency 'sqlite3', '~> 1.3.3'
28
28
 
29
29
  s.files = `git ls-files`.split("\n")
@@ -9,12 +9,18 @@ module PolyamorousHelper
9
9
  end
10
10
  end
11
11
 
12
- def new_join_dependency(klass, associations = {})
13
- Polyamorous::JoinDependency.new klass, associations, []
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
14
21
  end
15
22
 
16
23
  def new_join(name, type = Polyamorous::InnerJoin, klass = nil)
17
24
  Polyamorous::Join.new name, type, klass
18
25
  end
19
-
20
26
  end
@@ -2,10 +2,53 @@ require 'spec_helper'
2
2
 
3
3
  module Polyamorous
4
4
  describe JoinAssociation do
5
- if ActiveRecord::VERSION::STRING >= '4.1'
6
- include_examples 'Join Association on ActiveRecord 4.1'
7
- else
8
- include_examples 'Join Association on ActiveRecord 3 and 4.0'
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
9
52
  end
10
53
  end
11
54
  end
@@ -2,10 +2,101 @@ require 'spec_helper'
2
2
 
3
3
  module Polyamorous
4
4
  describe JoinDependency do
5
- if ActiveRecord::VERSION::STRING >= '4.1'
6
- include_examples 'Join Dependency on ActiveRecord 4.1'
7
- else
8
- include_examples 'Join Dependency on ActiveRecord 3 and 4.0'
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] }
9
100
  end
10
101
  end
11
102
  end
@@ -7,7 +7,7 @@ module Polyamorous
7
7
  expect(join).to be_kind_of(TreeNode)
8
8
  end
9
9
 
10
- it 'can be add to a tree' do
10
+ it 'can be added to a tree' do
11
11
  join = new_join(:articles, :outer)
12
12
 
13
13
  tree_hash = {}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polyamorous
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ernie Miller
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-04-05 00:00:00.000000000 Z
14
+ date: 2018-01-23 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activerecord
@@ -33,14 +33,14 @@ dependencies:
33
33
  requirements:
34
34
  - - "~>"
35
35
  - !ruby/object:Gem::Version
36
- version: 2.14.0
36
+ version: '3'
37
37
  type: :development
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: 2.14.0
43
+ version: '3'
44
44
  - !ruby/object:Gem::Dependency
45
45
  name: machinist
46
46
  requirement: !ruby/object:Gem::Requirement
@@ -61,14 +61,14 @@ dependencies:
61
61
  requirements:
62
62
  - - "~>"
63
63
  - !ruby/object:Gem::Version
64
- version: 0.9.5
64
+ version: 1.6.5
65
65
  type: :development
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
68
68
  requirements:
69
69
  - - "~>"
70
70
  - !ruby/object:Gem::Version
71
- version: 0.9.5
71
+ version: 1.6.5
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: sqlite3
74
74
  requirement: !ruby/object:Gem::Requirement
@@ -108,11 +108,17 @@ files:
108
108
  - lib/polyamorous/activerecord_4.1_ruby_1.9/join_dependency.rb
109
109
  - lib/polyamorous/activerecord_4.1_ruby_2/join_association.rb
110
110
  - lib/polyamorous/activerecord_4.1_ruby_2/join_dependency.rb
111
- - lib/polyamorous/activerecord_4.1_ruby_2/make_joins.rb
111
+ - lib/polyamorous/activerecord_4.1_ruby_2/make_polyamorous_inner_joins.rb
112
112
  - lib/polyamorous/activerecord_4.2_ruby_1.9/join_association.rb
113
113
  - lib/polyamorous/activerecord_4.2_ruby_1.9/join_dependency.rb
114
114
  - lib/polyamorous/activerecord_4.2_ruby_2/join_association.rb
115
115
  - lib/polyamorous/activerecord_4.2_ruby_2/join_dependency.rb
116
+ - lib/polyamorous/activerecord_5.0_ruby_2/join_association.rb
117
+ - lib/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb
118
+ - lib/polyamorous/activerecord_5.1_ruby_2/join_association.rb
119
+ - lib/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb
120
+ - lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb
121
+ - lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb
116
122
  - lib/polyamorous/join.rb
117
123
  - lib/polyamorous/swapping_reflection_class.rb
118
124
  - lib/polyamorous/tree_node.rb
@@ -129,10 +135,6 @@ files:
129
135
  - spec/polyamorous/join_spec.rb
130
136
  - spec/spec_helper.rb
131
137
  - spec/support/schema.rb
132
- - spec/support/shared_examples/join_association_3_and_4.0.rb
133
- - spec/support/shared_examples/join_association_4.1.rb
134
- - spec/support/shared_examples/join_dependency_3_and_4.0.rb
135
- - spec/support/shared_examples/join_dependency_4.1.rb
136
138
  homepage: https://github.com/activerecord-hackery/polyamorous
137
139
  licenses:
138
140
  - MIT
@@ -153,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
155
  version: '0'
154
156
  requirements: []
155
157
  rubyforge_project: polyamorous
156
- rubygems_version: 2.4.6
158
+ rubygems_version: 2.6.13
157
159
  signing_key:
158
160
  specification_version: 4
159
161
  summary: Loves/is loved by polymorphic belongs_to associations, Ransack, Squeel, MetaSearch...
@@ -169,7 +171,3 @@ test_files:
169
171
  - spec/polyamorous/join_spec.rb
170
172
  - spec/spec_helper.rb
171
173
  - spec/support/schema.rb
172
- - spec/support/shared_examples/join_association_3_and_4.0.rb
173
- - spec/support/shared_examples/join_association_4.1.rb
174
- - spec/support/shared_examples/join_dependency_3_and_4.0.rb
175
- - spec/support/shared_examples/join_dependency_4.1.rb
@@ -1,42 +0,0 @@
1
- shared_examples 'Join Association on ActiveRecord 3 and 4.0' do
2
- let(:join_dependency) { new_join_dependency Note, {} }
3
- let(:reflection) { Note.reflect_on_association(:notable) }
4
- let(:parent) { join_dependency.join_base }
5
- let(:join_association) {
6
- new_join_association(reflection, join_dependency, parent, Article)
7
- }
8
-
9
- subject {
10
- join_dependency.build_join_association_respecting_polymorphism(
11
- reflection, parent, Person
12
- )
13
- }
14
-
15
- it 'respects polymorphism on equality test' do
16
- expect(subject).to eq(
17
- join_dependency.build_join_association_respecting_polymorphism(
18
- reflection, parent, Person
19
- )
20
- )
21
- expect(subject).not_to eq(
22
- join_dependency.build_join_association_respecting_polymorphism(
23
- reflection, parent, Article
24
- )
25
- )
26
- end
27
-
28
- it 'leaves the orginal reflection intact for thread safety' do
29
- reflection.instance_variable_set(:@klass, Article)
30
- join_association
31
- .swapping_reflection_klass(reflection, Person) do |new_reflection|
32
- expect(new_reflection.options).not_to equal reflection.options
33
- expect(new_reflection.options).not_to have_key(:polymorphic)
34
- expect(new_reflection.klass).to eq(Person)
35
- expect(reflection.klass).to eq(Article)
36
- end
37
- end
38
-
39
- it 'sets the polmorphic option to true after initializing' do
40
- expect(join_association.options[:polymorphic]).to be_true
41
- end
42
- end
@@ -1,42 +0,0 @@
1
- shared_examples 'Join Association on ActiveRecord 4.1' do
2
- let(:join_dependency) { new_join_dependency Note, {} }
3
- let(:reflection) { Note.reflect_on_association(:notable) }
4
- let(:parent) { join_dependency.join_root }
5
- let(:join_association) {
6
- new_join_association(reflection, parent.children, Article)
7
- }
8
-
9
- subject {
10
- join_dependency.build_join_association_respecting_polymorphism(
11
- reflection, parent, Person
12
- )
13
- }
14
-
15
- it 'respects polymorphism on equality test' do
16
- expect(subject).to eq(
17
- join_dependency.build_join_association_respecting_polymorphism(
18
- reflection, parent, Person
19
- )
20
- )
21
- expect(subject).not_to eq(
22
- join_dependency.build_join_association_respecting_polymorphism(
23
- reflection, parent, Article
24
- )
25
- )
26
- end
27
-
28
- it 'leaves the orginal reflection intact for thread safety' do
29
- reflection.instance_variable_set(:@klass, Article)
30
- join_association
31
- .swapping_reflection_klass(reflection, Person) do |new_reflection|
32
- expect(new_reflection.options).not_to equal reflection.options
33
- expect(new_reflection.options).not_to have_key(:polymorphic)
34
- expect(new_reflection.klass).to eq(Person)
35
- expect(reflection.klass).to eq(Article)
36
- end
37
- end
38
-
39
- it 'sets the polmorphic option to true after initializing' do
40
- expect(join_association.reflection.options[:polymorphic]).to be_true
41
- end
42
- end
@@ -1,65 +0,0 @@
1
- shared_examples "Join Dependency on ActiveRecord 3 and 4.0" do
2
- context 'with symbol joins' do
3
- subject { new_join_dependency Person, :articles => :comments }
4
-
5
- specify { expect(subject.join_associations.size).to eq(2) }
6
- specify { expect(subject.join_associations)
7
- .to be_all { |a| a.join_type == Polyamorous::InnerJoin } }
8
- end
9
-
10
- context 'with has_many :through association' do
11
- subject { new_join_dependency Person, :authored_article_comments }
12
-
13
- specify { expect(subject.join_associations.size).to eq(1) }
14
- specify { expect(subject.join_associations.first.table_name)
15
- .to eq 'comments' }
16
- end
17
-
18
- context 'with outer join' do
19
- subject { new_join_dependency Person, new_join(:articles, :outer) }
20
-
21
- specify { expect(subject.join_associations.size).to eq(1) }
22
- specify { expect(subject.join_associations)
23
- .to be_all { |a| a.join_type == Polyamorous::OuterJoin } }
24
- end
25
-
26
- context 'with nested outer joins' do
27
- subject { new_join_dependency Person,
28
- new_join(:articles, :outer) => new_join(:comments, :outer) }
29
-
30
- specify { expect(subject.join_associations.size).to eq(2) }
31
- specify { expect(subject.join_associations)
32
- .to be_all { |a| a.join_type == Polyamorous::OuterJoin } }
33
- end
34
-
35
- context 'with polymorphic belongs_to join' do
36
- subject { new_join_dependency Note, new_join(:notable, :inner, Person) }
37
-
38
- specify { expect(subject.join_associations.size).to eq(1) }
39
- specify { expect(subject.join_associations)
40
- .to be_all { |a| a.join_type == Polyamorous::InnerJoin } }
41
- specify { expect(subject.join_associations.first.table_name)
42
- .to eq 'people' }
43
-
44
- it 'finds a join association respecting polymorphism' do
45
- parent = subject.join_base
46
- reflection = Note.reflect_on_association(:notable)
47
- expect(subject.find_join_association_respecting_polymorphism(
48
- reflection, parent, Person
49
- )).to eq subject.join_associations.first
50
- end
51
- end
52
-
53
- context 'with polymorphic belongs_to join and nested symbol join' do
54
- subject { new_join_dependency Note,
55
- new_join(:notable, :inner, Person) => :comments }
56
-
57
- specify { expect(subject.join_associations.size).to eq(2) }
58
- specify { expect(subject.join_associations)
59
- .to be_all { |a| a.join_type == Polyamorous::InnerJoin } }
60
- specify { expect(subject.join_associations.first.table_name)
61
- .to eq 'people' }
62
- specify { expect(subject.join_associations[1].table_name)
63
- .to eq 'comments' }
64
- end
65
- end
@@ -1,65 +0,0 @@
1
- shared_examples "Join Dependency on ActiveRecord 4.1" do
2
- context 'with symbol joins' do
3
- subject { new_join_dependency Person, :articles => :comments }
4
-
5
- specify { expect(subject.join_root.drop(1).size).to eq(2) }
6
- specify { expect(subject.join_root.drop(1).map(&:join_type))
7
- .to be_all { Polyamorous::InnerJoin } }
8
- end
9
-
10
- context 'with has_many :through association' do
11
- subject { new_join_dependency Person, :authored_article_comments }
12
-
13
- specify { expect(subject.join_root.drop(1).size).to eq(1) }
14
- specify { expect(subject.join_root.drop(1).first.table_name)
15
- .to eq 'comments' }
16
- end
17
-
18
- context 'with outer join' do
19
- subject { new_join_dependency Person, new_join(:articles, :outer) }
20
-
21
- specify { expect(subject.join_root.drop(1).size).to eq(1) }
22
- specify { expect(subject.join_root.drop(1).first.join_type)
23
- .to eq Polyamorous::OuterJoin }
24
- end
25
-
26
- context 'with nested outer joins' do
27
- subject { new_join_dependency Person,
28
- new_join(:articles, :outer) => new_join(:comments, :outer) }
29
-
30
- specify { expect(subject.join_root.drop(1).size).to eq(2) }
31
- specify { expect(subject.join_root.drop(1).map(&:join_type))
32
- .to be_all { Polyamorous::OuterJoin } }
33
- end
34
-
35
- context 'with polymorphic belongs_to join' do
36
- subject { new_join_dependency Note, new_join(:notable, :inner, Person) }
37
-
38
- specify { expect(subject.join_root.drop(1).size).to eq(1) }
39
- specify { expect(subject.join_root.drop(1).first.join_type)
40
- .to eq Polyamorous::InnerJoin }
41
- specify { expect(subject.join_root.drop(1).first.table_name)
42
- .to eq 'people' }
43
-
44
- it 'finds a join association respecting polymorphism' do
45
- parent = subject.join_root
46
- reflection = Note.reflect_on_association(:notable)
47
- expect(subject.find_join_association_respecting_polymorphism(
48
- reflection, parent, Person
49
- )).to eq subject.join_root.drop(1).first
50
- end
51
- end
52
-
53
- context 'with polymorphic belongs_to join and nested symbol join' do
54
- subject { new_join_dependency Note,
55
- new_join(:notable, :inner, Person) => :comments }
56
-
57
- specify { expect(subject.join_root.drop(1).size).to eq(2) }
58
- specify { expect(subject.join_root.drop(1).map(&:join_type))
59
- .to be_all { Polyamorous::InnerJoin } }
60
- specify { expect(subject.join_root.drop(1).first.table_name)
61
- .to eq 'people' }
62
- specify { expect(subject.join_root.drop(1)[1].table_name)
63
- .to eq 'comments' }
64
- end
65
- end