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 +4 -4
- data/CHANGELOG.md +6 -1
- data/baby_squeel.gemspec +1 -0
- data/lib/baby_squeel/active_record/query_methods.rb +10 -4
- data/lib/baby_squeel/association.rb +1 -1
- data/lib/baby_squeel/{join_expression.rb → join.rb} +2 -2
- data/lib/baby_squeel/join_dependency.rb +78 -0
- data/lib/baby_squeel/table.rb +6 -6
- data/lib/baby_squeel/version.rb +1 -1
- metadata +18 -5
- data/lib/baby_squeel/join_dependency/builder.rb +0 -121
- data/lib/baby_squeel/join_dependency/injector.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f491f71692c6a13ed97203fd5cf7c9b08afeac2b
|
4
|
+
data.tar.gz: 5da604986d6d6478b703414f9b78307871ca8adf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60f3bfa7c9de2b6fdcc470a65f23e945d340d538f1dd54f19237f8844a1c5b348d8cf713d74f36e7a333dc9e836fd44ae3b234acfc57173bb1556844963065f8
|
7
|
+
data.tar.gz: 5739d55d7eaf421f1091ab580cff50e263a73543ade85b4a43bab64a79342269111c988d8144daff5bb7eac72d511e38194256a124998352d2add127c19ed789
|
data/CHANGELOG.md
CHANGED
@@ -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.
|
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
|
data/baby_squeel.gemspec
CHANGED
@@ -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
|
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::
|
43
|
-
|
44
|
-
|
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
|
@@ -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
|
-
#
|
6
|
-
class
|
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
|
data/lib/baby_squeel/table.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'baby_squeel/resolver'
|
2
|
-
require 'baby_squeel/
|
3
|
-
require 'baby_squeel/join_dependency
|
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
|
-
|
88
|
-
builder.
|
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
|
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
|
-
|
105
|
+
Join.new(associations)
|
106
106
|
elsif associations.any?
|
107
107
|
associations.reverse.inject({}) do |names, assoc|
|
108
108
|
{ assoc._reflection.name => names }
|
data/lib/baby_squeel/version.rb
CHANGED
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.
|
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:
|
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/
|
120
|
-
- lib/baby_squeel/join_dependency
|
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
|