polyamorous 1.3.3 → 2.3.0

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