polyamorous 1.2.0 → 1.3.3

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.
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