baby_squeel 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49777d549c657b766ebef88cb758b6883cbf4e2e
4
- data.tar.gz: 5d4f4e51737e5b252ff0783303b7081cfd8b5d37
3
+ metadata.gz: f491f71692c6a13ed97203fd5cf7c9b08afeac2b
4
+ data.tar.gz: 5da604986d6d6478b703414f9b78307871ca8adf
5
5
  SHA512:
6
- metadata.gz: 4bf0eea8486a351b13221d37040202906e83b92da78570e5ddae25944ddc82e4ae31acaa9302f3ecb4948677a99966f6a0b297049045f40dc195cd5b9a7a8699
7
- data.tar.gz: 4d2a82db29d4613dc73a2079bd773bc1e75cf570f51375ab554e00a3c2ca28bd6f40d0c12402843e83986c6ca065de6ce3c0854c0958e36ebd3e741b99509143
6
+ metadata.gz: 60f3bfa7c9de2b6fdcc470a65f23e945d340d538f1dd54f19237f8844a1c5b348d8cf713d74f36e7a333dc9e836fd44ae3b234acfc57173bb1556844963065f8
7
+ data.tar.gz: 5739d55d7eaf421f1091ab580cff50e263a73543ade85b4a43bab64a79342269111c988d8144daff5bb7eac72d511e38194256a124998352d2add127c19ed789
@@ -2,6 +2,10 @@
2
2
 
3
3
  Nothing to see here.
4
4
 
5
+ ## [1.2.1] - 2018-04-25
6
+ ## Fixed
7
+ - Added support for Active Record 5.2
8
+
5
9
  ## [1.2.0] - 2017-10-20
6
10
  ### Added
7
11
  - `reordering`, which is just a BabySqueel version of Active Record's `reorder`.
@@ -127,7 +131,8 @@ Nothing to see here.
127
131
  ### Added
128
132
  - Initial support for selects, orders, wheres, and joins.
129
133
 
130
- [Unreleased]: https://github.com/rzane/baby_squeel/compare/v1.2.0...HEAD
134
+ [Unreleased]: https://github.com/rzane/baby_squeel/compare/v1.2.1...HEAD
135
+ [1.2.1]: https://github.com/rzane/baby_squeel/compare/v1.2.0...v1.2.1
131
136
  [1.2.0]: https://github.com/rzane/baby_squeel/compare/v1.1.5...v1.2.0
132
137
  [1.1.5]: https://github.com/rzane/baby_squeel/compare/v1.1.4...v1.1.5
133
138
  [1.1.4]: https://github.com/rzane/baby_squeel/compare/v1.1.3...v1.1.4
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_dependency 'activerecord', '>= 4.2.0'
23
23
  spec.add_dependency 'polyamorous', '~> 1.3'
24
+ spec.add_dependency 'join_dependency', '~> 0.1.1'
24
25
 
25
26
  spec.add_development_dependency 'bundler', '~> 1.11'
26
27
  spec.add_development_dependency 'rake', '~> 10.0'
@@ -1,5 +1,5 @@
1
1
  require 'baby_squeel/dsl'
2
- require 'baby_squeel/join_dependency/injector'
2
+ require 'baby_squeel/join_dependency'
3
3
 
4
4
  module BabySqueel
5
5
  module ActiveRecord
@@ -39,9 +39,15 @@ module BabySqueel
39
39
  # This is a monkey patch, and I'm not happy about it.
40
40
  # Active Record will call `group_by` on the `joins`. The
41
41
  # Injector has a custom `group_by` method that handles
42
- # BabySqueel::JoinExpression nodes.
43
- def build_joins(manager, joins)
44
- super manager, BabySqueel::JoinDependency::Injector.new(joins)
42
+ # BabySqueel::Join nodes.
43
+ if ::ActiveRecord::VERSION::MAJOR >= 5 && ::ActiveRecord::VERSION::MINOR >= 2
44
+ def build_joins(manager, joins, aliases)
45
+ super manager, BabySqueel::JoinDependency::Injector.new(joins), aliases
46
+ end
47
+ else
48
+ def build_joins(manager, joins)
49
+ super manager, BabySqueel::JoinDependency::Injector.new(joins)
50
+ end
45
51
  end
46
52
  end
47
53
  end
@@ -47,7 +47,7 @@ module BabySqueel
47
47
  _join == Arel::Nodes::OuterJoin || _reflection.polymorphic?
48
48
  end
49
49
 
50
- # See JoinExpression#add_to_tree.
50
+ # See Join#add_to_tree.
51
51
  def add_to_tree(hash)
52
52
  polyamorous = Polyamorous::Join.new(
53
53
  _reflection.name,
@@ -2,8 +2,8 @@ module BabySqueel
2
2
  # This is the thing that gets added to Active Record's joins_values.
3
3
  # By including Polyamorous::TreeNode, when this instance is found when
4
4
  # traversing joins in ActiveRecord::Associations::JoinDependency::walk_tree,
5
- # JoinExpression#add_to_tree will be called.
6
- class JoinExpression
5
+ # Join#add_to_tree will be called.
6
+ class Join
7
7
  include Polyamorous::TreeNode
8
8
 
9
9
  def initialize(associations)
@@ -0,0 +1,78 @@
1
+ require 'join_dependency'
2
+
3
+ module BabySqueel
4
+ module JoinDependency
5
+ # This class allows BabySqueel to slip custom
6
+ # joins_values into Active Record's JoinDependency
7
+ class Injector < Array # :nodoc:
8
+ # Active Record will call group_by on this object
9
+ # in ActiveRecord::QueryMethods#build_joins. This
10
+ # allows BabySqueel::Joins to be treated
11
+ # like typical join hashes until Polyamorous can
12
+ # deal with them.
13
+ def group_by
14
+ super do |join|
15
+ case join
16
+ when BabySqueel::Join
17
+ :association_join
18
+ else
19
+ yield join
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ class Builder # :nodoc:
26
+ attr_reader :join_dependency
27
+
28
+ def initialize(relation)
29
+ @join_dependency = ::JoinDependency.from_relation(relation) do |join|
30
+ :association_join if join.kind_of? BabySqueel::Join
31
+ end
32
+ end
33
+
34
+ # Find the alias of a BabySqueel::Association, by passing
35
+ # a list (in order of chaining) of associations and finding
36
+ # the respective JoinAssociation at each level.
37
+ def find_alias(associations)
38
+ table = find_join_association(associations).table
39
+ reconstruct_with_type_caster(table, associations)
40
+ end
41
+
42
+ private
43
+
44
+ def find_join_association(associations)
45
+ associations.inject(join_dependency.send(:join_root)) do |parent, assoc|
46
+ parent.children.find do |join_association|
47
+ reflections_equal?(
48
+ assoc._reflection,
49
+ join_association.reflection
50
+ )
51
+ end
52
+ end
53
+ end
54
+
55
+ # Compare two reflections and see if they're the same.
56
+ def reflections_equal?(a, b)
57
+ comparable_reflection(a) == comparable_reflection(b)
58
+ end
59
+
60
+ # Get the parent of the reflection if it has one.
61
+ # In AR4, #parent_reflection returns [name, reflection]
62
+ # In AR5, #parent_reflection returns just a reflection
63
+ def comparable_reflection(reflection)
64
+ [*reflection.parent_reflection].last || reflection
65
+ end
66
+
67
+ # Active Record 5's AliasTracker initializes Arel tables
68
+ # with the type_caster belonging to the wrong model.
69
+ #
70
+ # See: https://github.com/rails/rails/pull/27994
71
+ def reconstruct_with_type_caster(table, associations)
72
+ return table if ::ActiveRecord::VERSION::MAJOR < 5
73
+ type_caster = associations.last._scope.type_caster
74
+ ::Arel::Table.new(table.name, type_caster: type_caster)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,6 +1,6 @@
1
1
  require 'baby_squeel/resolver'
2
- require 'baby_squeel/join_expression'
3
- require 'baby_squeel/join_dependency/builder'
2
+ require 'baby_squeel/join'
3
+ require 'baby_squeel/join_dependency'
4
4
 
5
5
  module BabySqueel
6
6
  class Table
@@ -84,8 +84,8 @@ module BabySqueel
84
84
  # This method allows BabySqueel::Nodes::Attribute
85
85
  # instances to find what their alias will be.
86
86
  def find_alias(associations = [])
87
- builder = JoinDependency::Builder.new(_scope.all)
88
- builder.ensure_associated _arel(associations)
87
+ rel = _scope.joins _arel(associations)
88
+ builder = JoinDependency::Builder.new(rel)
89
89
  builder.find_alias(associations)
90
90
  end
91
91
 
@@ -96,13 +96,13 @@ module BabySqueel
96
96
  # 2. Implicit join without using an outer join. In this case, we'll just
97
97
  # give a hash to Active Record, and join the normal way.
98
98
  # 3. Implicit join using an outer join. In this case, we need to use
99
- # Polyamorous to build the join. We'll return a JoinExpression.
99
+ # Polyamorous to build the join. We'll return a Join.
100
100
  #
101
101
  def _arel(associations = [])
102
102
  if _on
103
103
  _join.new(_table, Arel::Nodes::On.new(_on))
104
104
  elsif associations.any?(&:needs_polyamorous?)
105
- JoinExpression.new(associations)
105
+ Join.new(associations)
106
106
  elsif associations.any?
107
107
  associations.reverse.inject({}) do |names, assoc|
108
108
  { assoc._reflection.name => names }
@@ -1,3 +1,3 @@
1
1
  module BabySqueel
2
- VERSION = '1.2.0'.freeze
2
+ VERSION = '1.2.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baby_squeel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ray Zane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-20 00:00:00.000000000 Z
11
+ date: 2018-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: join_dependency
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.1
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -116,9 +130,8 @@ files:
116
130
  - lib/baby_squeel/compat.rb
117
131
  - lib/baby_squeel/dsl.rb
118
132
  - lib/baby_squeel/errors.rb
119
- - lib/baby_squeel/join_dependency/builder.rb
120
- - lib/baby_squeel/join_dependency/injector.rb
121
- - lib/baby_squeel/join_expression.rb
133
+ - lib/baby_squeel/join.rb
134
+ - lib/baby_squeel/join_dependency.rb
122
135
  - lib/baby_squeel/nodes.rb
123
136
  - lib/baby_squeel/nodes/attribute.rb
124
137
  - lib/baby_squeel/nodes/binary.rb
@@ -1,121 +0,0 @@
1
- require 'baby_squeel/join_dependency/injector'
2
-
3
- module BabySqueel
4
- module JoinDependency
5
- # Unfortunately, this is mostly all duplication of
6
- # ActiveRecord::QueryMethods#build_joins
7
- class Builder # :nodoc:
8
- attr_reader :relation
9
-
10
- def initialize(relation)
11
- @relation = relation
12
- @joins_values = relation.joins_values.dup
13
- end
14
-
15
- def ensure_associated(*values)
16
- @joins_values += values
17
- end
18
-
19
- def join_dependency
20
- ::ActiveRecord::Associations::JoinDependency.new(
21
- relation.model,
22
- association_joins,
23
- join_list
24
- )
25
- end
26
- delegate :join_root, to: :join_dependency
27
-
28
- def find_join_association(associations)
29
- associations.inject(join_root) do |parent, assoc|
30
- parent.children.find do |join_association|
31
- reflections_equal?(
32
- assoc._reflection,
33
- join_association.reflection
34
- )
35
- end
36
- end
37
- end
38
-
39
- # Find the alias of a BabySqueel::Association, by passing
40
- # a list (in order of chaining) of associations and finding
41
- # the respective JoinAssociation at each level.
42
- def find_alias(associations)
43
- table = find_join_association(associations).table
44
- reconstruct_with_type_caster(table, associations)
45
- end
46
-
47
- private
48
-
49
- # Compare two reflections and see if they're the same.
50
- def reflections_equal?(a, b)
51
- comparable_reflection(a) == comparable_reflection(b)
52
- end
53
-
54
- # Get the parent of the reflection if it has one.
55
- # In AR4, #parent_reflection returns [name, reflection]
56
- # In AR5, #parent_reflection returns just a reflection
57
- def comparable_reflection(reflection)
58
- [*reflection.parent_reflection].last || reflection
59
- end
60
-
61
- # Active Record 5's AliasTracker initializes Arel tables
62
- # with the type_caster belonging to the wrong model.
63
- #
64
- # See: https://github.com/rails/rails/pull/27994
65
- def reconstruct_with_type_caster(table, associations)
66
- return table if ::ActiveRecord::VERSION::MAJOR < 5
67
- type_caster = associations.last._scope.type_caster
68
- ::Arel::Table.new(table.name, type_caster: type_caster)
69
- end
70
-
71
- def join_list
72
- join_nodes + join_strings_as_ast
73
- end
74
-
75
- def association_joins
76
- buckets[:association_join] || []
77
- end
78
-
79
- def stashed_association_joins
80
- buckets[:stashed_join] || []
81
- end
82
-
83
- def join_nodes
84
- (buckets[:join_node] || []).uniq
85
- end
86
-
87
- def string_joins
88
- (buckets[:string_join] || []).map(&:strip).uniq
89
- end
90
-
91
- if Arel::VERSION >= '7.0.0'
92
- def join_strings_as_ast
93
- manager = Arel::SelectManager.new(relation.table)
94
- relation.send(:convert_join_strings_to_ast, manager, string_joins)
95
- end
96
- else
97
- def join_strings_as_ast
98
- manager = Arel::SelectManager.new(relation.table.engine, relation.table)
99
- relation.send(:custom_join_ast, manager, string_joins)
100
- end
101
- end
102
-
103
- def buckets
104
- @buckets ||= Injector.new(@joins_values).group_by do |join|
105
- case join
106
- when String
107
- :string_join
108
- when Hash, Symbol, Array
109
- :association_join
110
- when ::ActiveRecord::Associations::JoinDependency
111
- :stashed_join
112
- when ::Arel::Nodes::Join
113
- :join_node
114
- else
115
- raise 'unknown class: %s' % join.class.name
116
- end
117
- end
118
- end
119
- end
120
- end
121
- end
@@ -1,23 +0,0 @@
1
- module BabySqueel
2
- module JoinDependency
3
- # This class allows BabySqueel to slip custom
4
- # joins_values into Active Record's JoinDependency
5
- class Injector < Array # :nodoc:
6
- # Active Record will call group_by on this object
7
- # in ActiveRecord::QueryMethods#build_joins. This
8
- # allows BabySqueel::JoinExpressions to be treated
9
- # like typical join hashes until Polyamorous can
10
- # deal with them.
11
- def group_by
12
- super do |join|
13
- case join
14
- when BabySqueel::JoinExpression
15
- :association_join
16
- else
17
- yield join
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end