baby_squeel 1.4.0.beta1 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +106 -9
- data/ISSUE_TEMPLATE.md +1 -1
- data/README.md +1 -1
- data/baby_squeel.gemspec +2 -3
- data/lib/baby_squeel/active_record/calculations.rb +0 -13
- data/lib/baby_squeel/active_record/query_methods.rb +49 -10
- data/lib/baby_squeel/active_record/version_helper.rb +21 -0
- data/lib/baby_squeel/association.rb +10 -10
- data/lib/baby_squeel/calculation.rb +11 -13
- data/lib/baby_squeel/errors.rb +0 -10
- data/lib/baby_squeel/join_dependency.rb +114 -10
- data/lib/baby_squeel/version.rb +1 -1
- metadata +18 -26
- data/lib/baby_squeel/pluck.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54dbc98299ab8f9909d8c312e9663cc615543ea6421b81f2aab6efdd2bd9fe59
|
4
|
+
data.tar.gz: 97cc39dced57e0bd6bf16c854859f47902a2d6550e71c4120643fb01d0de9529
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f5e68cf4ac0e85d2dc8fce1741f2d64c2bd5b5ecc08c335d71ad3fae335fb3b580f5c3aa2c5f98053ec445d9a7fbc1d3ddec6c7218c99bcb9869a6767fa68c8
|
7
|
+
data.tar.gz: ca66ea54876dfb670177ccea3be1808c90b4d1affea3b7bc1cb5c515e6e8208a8b55fb9fcd06202c6411ea102a358ceb0aa7d0468f82ee7c857045fbc0c5e946
|
data/CHANGELOG.md
CHANGED
@@ -1,134 +1,224 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
-
|
3
|
+
## [1.4.4] - 2022-02-07
|
4
|
+
|
5
|
+
### Fixed
|
6
|
+
|
7
|
+
- Nested merge-joins query causes NoMethodError with ActiveRecord 6.1.4.4 (#119)
|
8
|
+
|
9
|
+
## [1.4.3] - 2022-02-04
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
- ActiveRecord::Relation#left_joins performs INNER JOIN on Active Record 6.1 (#118)
|
14
|
+
|
15
|
+
## [1.4.2] - 2022-01-24
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
- Added support for activerecord 7.0 (#116)
|
20
|
+
- Added support for activerecord 6.1 (#116)
|
21
|
+
- Added support for activerecord 6.0 (#116)
|
22
|
+
|
23
|
+
## [1.4.1] - 2021-06-17
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
|
27
|
+
- Fixed a bug related to checking the Active Record version.
|
28
|
+
|
29
|
+
## [1.4.0] - 2021-06-17
|
30
|
+
|
31
|
+
### Fixed
|
32
|
+
|
33
|
+
- Fix table alias when joining a polymorphic table twice (#108)
|
34
|
+
- Removed internal class `BabySqueel::Pluck`. You can still use `plucking`. For example, `Post.joining { author }.plucking { author.name }`
|
35
|
+
- Removed old code from Active Record < 5.2
|
36
|
+
- Removed dependency `join_dependency`
|
37
|
+
|
38
|
+
## [1.4.0.beta1] - 2021-04-21
|
39
|
+
|
40
|
+
### Fixed
|
41
|
+
|
42
|
+
- Add Support for activerecord '>= 5.2.3'
|
43
|
+
- Drop Support for Active Record versions that have reached EOL (activerecord < 5.2)
|
44
|
+
- Use polyamorous from ransack '~> 2.3'
|
4
45
|
|
5
46
|
## [1.3.1] - 2018-05-15
|
6
|
-
|
47
|
+
|
48
|
+
### Fixed
|
49
|
+
|
7
50
|
- Upgraded `join_dependency` requirement, which fixes [issue #1](https://github.com/rzane/join_dependency/issues/1).
|
8
51
|
|
9
52
|
## [1.3.0] - 2018-05-04
|
10
|
-
|
53
|
+
|
54
|
+
### Added
|
55
|
+
|
11
56
|
- The ability to use `plucking` with an array of nodes. For example, `User.plucking { [id, name] }`.
|
12
57
|
|
13
58
|
## [1.2.1] - 2018-04-25
|
14
|
-
|
59
|
+
|
60
|
+
### Fixed
|
61
|
+
|
15
62
|
- Added support for Active Record 5.2
|
16
63
|
|
17
64
|
## [1.2.0] - 2017-10-20
|
65
|
+
|
18
66
|
### Added
|
67
|
+
|
19
68
|
- `reordering`, which is just a BabySqueel version of Active Record's `reorder`.
|
20
69
|
- `on` expressions can now be given a block that will yield the current node (#77).
|
21
70
|
|
22
71
|
## [1.1.5] - 2017-05-26
|
72
|
+
|
23
73
|
### Fixed
|
74
|
+
|
24
75
|
- Returning an empty hash from a `where.has {}` block would generate invalid SQL (#69).
|
25
76
|
|
26
77
|
## [1.1.4] - 2017-04-13
|
78
|
+
|
27
79
|
### Fixed
|
80
|
+
|
28
81
|
- Nodes::Attribute#in and #not_in generate valid SQL when given ActiveRecord::NullRelations.
|
29
82
|
|
30
83
|
## [1.1.3] - 2017-03-31
|
84
|
+
|
31
85
|
### Fixed
|
86
|
+
|
32
87
|
- Nodes::Attribute#in was not returning BabySqueel node. As a result, you couldn't chain on it. This fixes #61.
|
33
88
|
|
34
89
|
## [1.1.2] - 2017-03-21
|
90
|
+
|
35
91
|
### Fixed
|
92
|
+
|
36
93
|
- Check if a reflection has a parent reflection before comparing them. This fixes #56.
|
37
94
|
|
38
95
|
### Refactored
|
96
|
+
|
39
97
|
- The logic encapsulated in `#method_missing` and `#respond_to_missing?` was difficult to follow, because it was falling back to `super`, sometimes going up the inheritance tree multiple levels. The addition of `BabySqueel::Resolver` now handles this a little more gracefully.
|
40
98
|
|
41
99
|
## [1.1.1] - 2017-02-14
|
100
|
+
|
42
101
|
### Fixed
|
102
|
+
|
43
103
|
- There is a bug in Active Record where the `AliasTracker` initializes `Arel::Table`s use the wrong `type_caster`. To address this, BabySqueel must re-initialize the `Arel::Table` with the correct `type_caster` (#54).
|
44
104
|
|
45
105
|
## [1.1.0] - 2017-02-10
|
106
|
+
|
46
107
|
> This version drops support for Active Record 4.1. If you're stil on 4.1, you should seriously consider upgrading to at least 4.2.
|
47
108
|
|
48
109
|
### Added
|
110
|
+
|
49
111
|
- DSLs for ActiveRecord::Relation::Calculations. You can now use `plucking`, `counting`, `summing`, `averaging`, `minimizing`, and `maximizing`.
|
50
112
|
|
51
113
|
## [1.0.3] - 2017-02-09
|
114
|
+
|
52
115
|
### Added
|
116
|
+
|
53
117
|
- Support for `pluck`.
|
54
118
|
- Support for `not_in`.
|
55
119
|
|
56
120
|
## [1.0.2] - 2017-02-07
|
121
|
+
|
57
122
|
### Added
|
123
|
+
|
58
124
|
- `BabySqueel::Association` now has `#==` and `#!=`. This is only supported for Rails 5+. Example: `Post.where { author: Author.last }`.
|
59
125
|
|
60
126
|
### Fixed
|
127
|
+
|
61
128
|
- Incorrect alias detection caused by not tracking the full path to a join (#37).
|
62
129
|
|
63
130
|
## [1.0.1] - 2016-11-07
|
131
|
+
|
64
132
|
### Added
|
65
|
-
|
133
|
+
|
134
|
+
- Add DSL#\_ for wrapping expressions in Arel::Node::Grouping. Thanks to [@odedniv].
|
66
135
|
|
67
136
|
### Fixed
|
137
|
+
|
68
138
|
- Use strings for attribute names like Rails does. Symbols were preventing things like `unscope` from working. Thanks to [@chewi].
|
69
139
|
- `where.has {}` will now accept `nil`.
|
70
140
|
- Arel::Nodes::Function did not previously include Arel::Math, so now you can do math operations on the result of SQL functions.
|
71
141
|
- Arel::Nodes::Binary did not previously include Arel::AliasPredication. Binary nodes can now be aliased using `as`.
|
72
142
|
|
73
143
|
## [1.0.0] - 2016-09-09
|
144
|
+
|
74
145
|
### Added
|
75
|
-
|
146
|
+
|
147
|
+
- Polyamorous. Unfortunately, this _does_ monkey-patch Active Record internals, but there just isn't any other reliable way to generate outer joins. Baby Squeel, itself, will still keep monkey patching to an absolute minimum.
|
76
148
|
- Within DSL blocks, you can use `exists` and `not_exists` with Active Record relations. For example: `Post.where.has { exists Post.where(title: 'Fun') }`.`
|
77
149
|
- Support for polymorphic associations.
|
78
150
|
|
79
151
|
### Deprecations
|
152
|
+
|
80
153
|
- Removed support for Active Record 4.0.x
|
81
154
|
|
82
155
|
### Changed
|
156
|
+
|
83
157
|
- BabySqueel::JoinDependency is no longer a class responsible for creating Arel joins. It is now a namespace for utilities used when working with the ActiveRecord::Association::JoinDependency class.
|
84
158
|
- BabySqueel::Nodes::Generic is now BabySqueel::Nodes::Node.
|
85
159
|
- Arel nodes are only extended with the behaviors they need. Previously, all Arel nodes were being extended with `Arel::AliasPredication`, `Arel::OrderPredications`, and `Arel::Math`.
|
86
160
|
|
87
161
|
### Fixed
|
162
|
+
|
88
163
|
- Fixed deprecation warnings on Active Record 5 when initializing an Arel::Table without a type caster.
|
89
164
|
- No more duplicate joins. Previously, Baby Squeel did a very poor job of ensuring that you didn't join an association twice.
|
90
|
-
- Alias detection should now
|
165
|
+
- Alias detection should now _actually_ work. The previous implementation was naive.
|
91
166
|
|
92
167
|
## [0.3.1] - 2016-08-02
|
168
|
+
|
93
169
|
### Added
|
170
|
+
|
94
171
|
- Ported backticks and #my from Squeel
|
95
172
|
|
96
173
|
### Changed
|
174
|
+
|
97
175
|
- DSL#sql now returns a node wrapped in a BabySqueel proxy.
|
98
176
|
|
99
177
|
## [0.3.0] - 2016-06-26
|
178
|
+
|
100
179
|
### Added
|
180
|
+
|
101
181
|
- Added Squeel compatibility mode that allows `select`, `order`, `joins`, `group`, `where`, and `having` to accept DSL blocks.
|
102
182
|
- Added the ability to query tables that aren't backed by Active Record models.
|
103
183
|
- Added `BabySqueel::[]`, which provides a `BabySqueel::Relation` for models, or a `BabySqueel::Table` for symbols/strings.
|
104
184
|
|
105
185
|
### Changed
|
186
|
+
|
106
187
|
- Renamed `BabySqueel::Association::AliasingError` to `BabySqueel::AssociationAliasingError`.
|
107
188
|
|
108
189
|
## [0.2.2] - 2016-03-30
|
190
|
+
|
109
191
|
### Added
|
192
|
+
|
110
193
|
- Support for `group` (`grouping`) and `having` (`when_having`).
|
111
194
|
- Support for sifters.
|
112
195
|
- Added `quoted` and `sql` helpers for quoting strings and SQL literals.
|
113
196
|
- More descriptive error messages when a column or association is not found.
|
114
197
|
|
115
198
|
### Fixed
|
199
|
+
|
116
200
|
- `Arel::Nodes::Grouping` does not include `Arel::Math`, so operations like `(id + 5) + 3` would fail unexpectedly.
|
117
201
|
- Fix missing bind values When joining through associations with default scope.
|
118
202
|
- Removed `ActiveRecord::VERSION` specific handling of the `WhereChain`.
|
119
203
|
|
120
204
|
## [0.2.1] - 2016-03-27
|
205
|
+
|
121
206
|
### Added
|
207
|
+
|
122
208
|
- Support for subqueries.
|
123
209
|
|
124
210
|
### Fixed
|
211
|
+
|
125
212
|
- Some Arel nodes did not have access to `as` expressions.
|
126
213
|
|
127
214
|
## [0.2.0] - 2016-03-25
|
215
|
+
|
128
216
|
### Added
|
217
|
+
|
129
218
|
- References to aliased joins in a `select`, `where`, or `order` expression now use the aliased table name.
|
130
219
|
|
131
220
|
### Changed
|
221
|
+
|
132
222
|
- Rely on `ActiveRecord::Relation#join_sources` for the implicit construction of join nodes, rather than using the `ActiveRecord::Associations::JoinDependency` directly.
|
133
223
|
|
134
224
|
### Fixed
|
@@ -136,10 +226,18 @@ Nothing to see here.
|
|
136
226
|
- Associations referencing the same table weren't being aliased.
|
137
227
|
|
138
228
|
## [0.1.0] - 2016-03-16
|
229
|
+
|
139
230
|
### Added
|
231
|
+
|
140
232
|
- Initial support for selects, orders, wheres, and joins.
|
141
233
|
|
142
|
-
[
|
234
|
+
[unreleased]: https://github.com/rzane/baby_squeel/compare/v1.4.4...HEAD
|
235
|
+
[1.4.4]: https://github.com/rzane/baby_squeel/compare/v1.4.3...v1.4.4
|
236
|
+
[1.4.3]: https://github.com/rzane/baby_squeel/compare/v1.4.2...v1.4.3
|
237
|
+
[1.4.2]: https://github.com/rzane/baby_squeel/compare/v1.4.1...v1.4.2
|
238
|
+
[1.4.1]: https://github.com/rzane/baby_squeel/compare/v1.4.0...v1.4.1
|
239
|
+
[1.4.0]: https://github.com/rzane/baby_squeel/compare/v1.4.0.beta1...v1.4.0
|
240
|
+
[1.4.0.beta1]: https://github.com/rzane/baby_squeel/compare/v1.3.1...v1.4.0.beta1
|
143
241
|
[1.3.1]: https://github.com/rzane/baby_squeel/compare/v1.3.0...v1.3.1
|
144
242
|
[1.3.0]: https://github.com/rzane/baby_squeel/compare/v1.2.1...v1.3.0
|
145
243
|
[1.2.1]: https://github.com/rzane/baby_squeel/compare/v1.2.0...v1.2.1
|
@@ -159,6 +257,5 @@ Nothing to see here.
|
|
159
257
|
[0.2.2]: https://github.com/rzane/baby_squeel/compare/v0.2.1...v0.2.2
|
160
258
|
[0.2.1]: https://github.com/rzane/baby_squeel/compare/v0.2.0...v0.2.1
|
161
259
|
[0.2.0]: https://github.com/rzane/baby_squeel/compare/v0.1.0...v0.2.0
|
162
|
-
|
163
260
|
[@chewi]: https://github.com/chewi
|
164
261
|
[@odedniv]: https://github.com/odedniv
|
data/ISSUE_TEMPLATE.md
CHANGED
@@ -11,7 +11,7 @@ require 'minitest/autorun'
|
|
11
11
|
|
12
12
|
gemfile true do
|
13
13
|
source 'https://rubygems.org'
|
14
|
-
gem 'activerecord', '~> 5.
|
14
|
+
gem 'activerecord', '~> 5.2.0' # which Active Record version?
|
15
15
|
gem 'sqlite3'
|
16
16
|
gem 'baby_squeel', github: 'rzane/baby_squeel'
|
17
17
|
end
|
data/README.md
CHANGED
@@ -329,7 +329,7 @@ Check out the [migration guide](https://github.com/rzane/baby_squeel/wiki/Migrat
|
|
329
329
|
|
330
330
|
## Development
|
331
331
|
|
332
|
-
1. Pick an Active Record version to develop against, then export it: `export AR=
|
332
|
+
1. Pick an Active Record version to develop against, then export it: `export AR=6.1.4`.
|
333
333
|
2. Run `bin/setup` to install dependencies.
|
334
334
|
3. Run `rake` to run the specs.
|
335
335
|
|
data/baby_squeel.gemspec
CHANGED
@@ -19,12 +19,11 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.files = Dir.glob('{lib/**/*,*.{md,txt,gemspec}}')
|
21
21
|
|
22
|
-
spec.add_dependency 'activerecord', '
|
22
|
+
spec.add_dependency 'activerecord', '>= 5.2', '< 7.1'
|
23
23
|
spec.add_dependency 'ransack', '~> 2.3'
|
24
|
-
spec.add_dependency 'join_dependency', '~> 0.1.4'
|
25
24
|
|
26
25
|
spec.add_development_dependency 'bundler', '~> 2'
|
27
26
|
spec.add_development_dependency 'rake', '~> 13.0'
|
28
27
|
spec.add_development_dependency 'rspec', '~> 3.10'
|
29
|
-
spec.add_development_dependency 'sqlite3'
|
28
|
+
spec.add_development_dependency 'sqlite3'
|
30
29
|
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
require 'baby_squeel/calculation'
|
2
|
-
require 'baby_squeel/pluck'
|
3
2
|
|
4
3
|
module BabySqueel
|
5
4
|
module ActiveRecord
|
6
5
|
module Calculations
|
7
6
|
def plucking(&block)
|
8
7
|
nodes = Array.wrap(DSL.evaluate(self, &block))
|
9
|
-
nodes = nodes.map { |node| Pluck.decorate(node) }
|
10
8
|
pluck(*nodes)
|
11
9
|
end
|
12
10
|
|
@@ -40,17 +38,6 @@ module BabySqueel
|
|
40
38
|
super
|
41
39
|
end
|
42
40
|
end
|
43
|
-
|
44
|
-
if ::ActiveRecord::VERSION::MAJOR < 5
|
45
|
-
# @override
|
46
|
-
def type_for(field)
|
47
|
-
if field.kind_of? Calculation
|
48
|
-
field
|
49
|
-
else
|
50
|
-
super
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
41
|
end
|
55
42
|
end
|
56
43
|
end
|
@@ -1,9 +1,26 @@
|
|
1
1
|
require 'baby_squeel/dsl'
|
2
2
|
require 'baby_squeel/join_dependency'
|
3
|
+
require 'baby_squeel/active_record/version_helper'
|
3
4
|
|
4
5
|
module BabySqueel
|
5
6
|
module ActiveRecord
|
6
7
|
module QueryMethods
|
8
|
+
# This class allows BabySqueel to slip custom
|
9
|
+
# joins_values into Active Record's JoinDependency
|
10
|
+
module Injector6_1
|
11
|
+
def each(&block)
|
12
|
+
super do |join|
|
13
|
+
if join.is_a?(BabySqueel::Join)
|
14
|
+
result = block.binding.local_variables.include?(:result) && block.binding.local_variable_get(:result)
|
15
|
+
result << join if result
|
16
|
+
join
|
17
|
+
else
|
18
|
+
block.call(join)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
7
24
|
# Constructs Arel for ActiveRecord::QueryMethods#joins using the DSL.
|
8
25
|
def joining(&block)
|
9
26
|
joins DSL.evaluate(self, &block)
|
@@ -34,19 +51,41 @@ module BabySqueel
|
|
34
51
|
having DSL.evaluate(self, &block)
|
35
52
|
end
|
36
53
|
|
37
|
-
|
54
|
+
if BabySqueel::ActiveRecord::VersionHelper.at_least_6_1?
|
55
|
+
def construct_join_dependency(associations, join_type)
|
56
|
+
result = super(associations, join_type)
|
57
|
+
if associations.any? { |assoc| assoc.is_a?(BabySqueel::Join) }
|
58
|
+
result.extend(BabySqueel::JoinDependency::Injector6_1)
|
59
|
+
end
|
60
|
+
result
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
# https://github.com/rails/rails/commit/c0c53ee9d28134757cf1418521cb97c4a135f140
|
66
|
+
def select_association_list(*args)
|
67
|
+
args[0].extend(BabySqueel::ActiveRecord::QueryMethods::Injector6_1)
|
68
|
+
super *args
|
69
|
+
end
|
70
|
+
elsif BabySqueel::ActiveRecord::VersionHelper.at_least_6_0?
|
71
|
+
private
|
38
72
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
super manager, BabySqueel::JoinDependency::Injector.new(joins), aliases
|
73
|
+
# Active Record will call `each` on the `joins`. The
|
74
|
+
# Injector has a custom `each` method that handles
|
75
|
+
# BabySqueel::Join nodes.
|
76
|
+
def build_joins(*args)
|
77
|
+
args[1] = BabySqueel::JoinDependency::Injector6_0.new(args.second)
|
78
|
+
super(*args)
|
46
79
|
end
|
47
80
|
else
|
48
|
-
|
49
|
-
|
81
|
+
private
|
82
|
+
|
83
|
+
# Active Record will call `group_by` on the `joins`. The
|
84
|
+
# Injector has a custom `group_by` method that handles
|
85
|
+
# BabySqueel::Join nodes.
|
86
|
+
def build_joins(*args)
|
87
|
+
args[1] = BabySqueel::JoinDependency::Injector5_2.new(args.second)
|
88
|
+
super(*args)
|
50
89
|
end
|
51
90
|
end
|
52
91
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'baby_squeel/dsl'
|
2
|
+
|
3
|
+
module BabySqueel
|
4
|
+
module ActiveRecord
|
5
|
+
class VersionHelper
|
6
|
+
def self.at_least_6_1?
|
7
|
+
::ActiveRecord::VERSION::MAJOR > 6 ||
|
8
|
+
::ActiveRecord::VERSION::MAJOR == 6 && ::ActiveRecord::VERSION::MINOR >= 1
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.at_least_6_0?
|
12
|
+
::ActiveRecord::VERSION::MAJOR >= 6
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.at_least_5_2_3?
|
16
|
+
at_least_6_0? ||
|
17
|
+
::ActiveRecord::VERSION::MAJOR >= 5 && ::ActiveRecord::VERSION::MINOR >= 2 && ::ActiveRecord::VERSION::TINY >= 3
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'baby_squeel/relation'
|
2
|
+
require 'baby_squeel/active_record/version_helper'
|
2
3
|
|
3
4
|
module BabySqueel
|
4
5
|
class Association < Relation
|
@@ -96,19 +97,18 @@ module BabySqueel
|
|
96
97
|
|
97
98
|
private
|
98
99
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
def build_where_clause(other)
|
101
|
+
if valid_where_clause?(other)
|
102
|
+
relation = @parent._scope.all
|
103
|
+
|
104
|
+
if BabySqueel::ActiveRecord::VersionHelper.at_least_6_1?
|
105
|
+
relation.send(:build_where_clause, { _reflection.name => other }, [])
|
106
|
+
else
|
103
107
|
factory = relation.send(:where_clause_factory)
|
104
108
|
factory.build({ _reflection.name => other }, [])
|
105
|
-
else
|
106
|
-
raise AssociationComparisonError.new(_reflection.name, other)
|
107
109
|
end
|
108
|
-
|
109
|
-
|
110
|
-
def build_where_clause(_)
|
111
|
-
raise AssociationComparisonNotSupportedError.new(_reflection.name)
|
110
|
+
else
|
111
|
+
raise AssociationComparisonError.new(_reflection.name, other)
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
@@ -6,12 +6,6 @@ module BabySqueel
|
|
6
6
|
@node = node
|
7
7
|
end
|
8
8
|
|
9
|
-
# This is only used in 4.2. We're just pretending to be
|
10
|
-
# a database column to fake the casting here.
|
11
|
-
def type_cast_from_database(value)
|
12
|
-
value
|
13
|
-
end
|
14
|
-
|
15
9
|
# In Active Record 5, we don't *need* this class to make
|
16
10
|
# calculations work. They happily accept arel. However,
|
17
11
|
# when grouping with a calculation, there's a really,
|
@@ -21,15 +15,19 @@ module BabySqueel
|
|
21
15
|
# caching because the alias would have a unique name every
|
22
16
|
# time.
|
23
17
|
def to_s
|
24
|
-
|
25
|
-
|
26
|
-
child.
|
27
|
-
|
28
|
-
child.name
|
18
|
+
if node.respond_to?(:map)
|
19
|
+
names = node.map do |child|
|
20
|
+
if child.kind_of?(String) || child.kind_of?(Symbol)
|
21
|
+
child.to_s
|
22
|
+
elsif child.respond_to?(:name)
|
23
|
+
child.name.to_s
|
24
|
+
end
|
29
25
|
end
|
26
|
+
names.compact.uniq.join('_')
|
27
|
+
else
|
28
|
+
# fix for https://github.com/rails/rails/commit/fc38ff6e4417295c870f419f7c164ab5a7dbc4a5
|
29
|
+
node.to_sql.split('"').map { |v| v.tr('^A-Za-z0-9_', '').presence }.compact.uniq.join('_')
|
30
30
|
end
|
31
|
-
|
32
|
-
names.compact.uniq.join('_')
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
data/lib/baby_squeel/errors.rb
CHANGED
@@ -62,14 +62,4 @@ module BabySqueel
|
|
62
62
|
super "You can't compare association '#{name}' to #{other}."
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
66
|
-
class AssociationComparisonNotSupportedError < StandardError # :nodoc:
|
67
|
-
MESSAGE =
|
68
|
-
"Querying association '%{name}' with '==' and '!=' " \
|
69
|
-
"is only supported for ActiveRecord >=5."
|
70
|
-
|
71
|
-
def initialize(name)
|
72
|
-
super format(MESSAGE, name: name)
|
73
|
-
end
|
74
|
-
end
|
75
65
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'baby_squeel/active_record/version_helper'
|
2
2
|
|
3
3
|
module BabySqueel
|
4
4
|
module JoinDependency
|
5
5
|
# This class allows BabySqueel to slip custom
|
6
6
|
# joins_values into Active Record's JoinDependency
|
7
|
-
class
|
7
|
+
class Injector5_2 < Array # :nodoc:
|
8
8
|
# Active Record will call group_by on this object
|
9
9
|
# in ActiveRecord::QueryMethods#build_joins. This
|
10
10
|
# allows BabySqueel::Joins to be treated
|
@@ -22,23 +22,63 @@ module BabySqueel
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
# This class allows BabySqueel to slip custom
|
26
|
+
# joins_values into Active Record's JoinDependency
|
27
|
+
class Injector6_0 < Array # :nodoc:
|
28
|
+
# https://github.com/rails/rails/pull/36805/files
|
29
|
+
# This commit changed group_by to each
|
30
|
+
def each(&block)
|
31
|
+
super do |join|
|
32
|
+
if block.binding.local_variables.include?(:buckets)
|
33
|
+
buckets = block.binding.local_variable_get(:buckets)
|
34
|
+
|
35
|
+
case join
|
36
|
+
when BabySqueel::Join
|
37
|
+
buckets[:association_join] << join
|
38
|
+
else
|
39
|
+
block.call(join)
|
40
|
+
end
|
41
|
+
else
|
42
|
+
block.call(join)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# This is a 'fix' for the left outer joins
|
49
|
+
# rails way would be to call left_outer_joins so the join_type gets set to Arel::Nodes::OuterJoin
|
50
|
+
# Maybe this could be fixed in joining but I do not know how.
|
51
|
+
module Injector6_1 # :nodoc:
|
52
|
+
def make_constraints(parent, child, join_type) # :nodoc:
|
53
|
+
join_type = child.join_type if child.join_type == Arel::Nodes::OuterJoin
|
54
|
+
super(parent, child, join_type)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
25
58
|
class Builder # :nodoc:
|
26
59
|
attr_reader :join_dependency
|
27
60
|
|
28
61
|
def initialize(relation)
|
29
|
-
@join_dependency =
|
30
|
-
:association_join if join.kind_of? BabySqueel::Join
|
31
|
-
end
|
62
|
+
@join_dependency = build(relation, collect_joins(relation))
|
32
63
|
end
|
33
64
|
|
34
65
|
# Find the alias of a BabySqueel::Association, by passing
|
35
66
|
# a list (in order of chaining) of associations and finding
|
36
67
|
# the respective JoinAssociation at each level.
|
37
68
|
def find_alias(associations)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
69
|
+
if BabySqueel::ActiveRecord::VersionHelper.at_least_6_1?
|
70
|
+
# construct_tables! got removed by rails
|
71
|
+
# https://github.com/rails/rails/commit/590b045ee2c0906ff162e6658a184afb201865d7
|
72
|
+
#
|
73
|
+
# construct_tables_for_association! is a method from the polyamorous (ransack) gem
|
74
|
+
join_root = join_dependency.send(:join_root)
|
75
|
+
join_root.each_children do |parent, child|
|
76
|
+
join_dependency.construct_tables_for_association!(parent, child)
|
77
|
+
end
|
78
|
+
elsif BabySqueel::ActiveRecord::VersionHelper.at_least_5_2_3?
|
79
|
+
# If we tell join_dependency to construct its tables, Active Record
|
80
|
+
# handles building the correct aliases and attaching them to its
|
81
|
+
# JoinDepenencies.
|
42
82
|
join_dependency.send(:construct_tables!, join_dependency.send(:join_root))
|
43
83
|
end
|
44
84
|
|
@@ -48,17 +88,81 @@ module BabySqueel
|
|
48
88
|
|
49
89
|
private
|
50
90
|
|
91
|
+
Associations = ::ActiveRecord::Associations
|
92
|
+
|
51
93
|
def find_join_association(associations)
|
52
94
|
current = join_dependency.send(:join_root)
|
53
95
|
|
54
96
|
associations.each do |association|
|
55
97
|
name = association._reflection.name
|
56
|
-
current = current.children.find { |c| c.reflection.name == name }
|
98
|
+
current = current.children.find { |c| c.reflection.name == name && klass_equal?(association, c) }
|
57
99
|
break if current.nil?
|
58
100
|
end
|
59
101
|
|
60
102
|
current
|
61
103
|
end
|
104
|
+
|
105
|
+
# If association is not polymorphic return true.
|
106
|
+
# If association is polymorphic compare the association polymorphic class with the join association base_klass
|
107
|
+
def klass_equal?(assoc, join_association)
|
108
|
+
return true unless assoc._reflection.polymorphic?
|
109
|
+
|
110
|
+
assoc._polymorphic_klass == join_association.base_klass
|
111
|
+
end
|
112
|
+
|
113
|
+
def collect_joins(relation)
|
114
|
+
joins = []
|
115
|
+
joins += relation.joins_values
|
116
|
+
joins += relation.left_outer_joins_values
|
117
|
+
|
118
|
+
buckets = joins.group_by do |join|
|
119
|
+
case join
|
120
|
+
when String
|
121
|
+
:string_join
|
122
|
+
when Hash, Symbol, Array
|
123
|
+
:association_join
|
124
|
+
when Associations::JoinDependency
|
125
|
+
:stashed_join
|
126
|
+
when Arel::Nodes::Join
|
127
|
+
:join_node
|
128
|
+
when BabySqueel::Join
|
129
|
+
:association_join
|
130
|
+
else
|
131
|
+
raise("unknown class: %s" % join.class.name)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def build(relation, buckets)
|
137
|
+
buckets.default = []
|
138
|
+
association_joins = buckets[:association_join]
|
139
|
+
stashed_association_joins = buckets[:stashed_join]
|
140
|
+
join_nodes = buckets[:join_node].uniq
|
141
|
+
string_joins = buckets[:string_join].map(&:strip).uniq
|
142
|
+
|
143
|
+
joins = string_joins.map do |join|
|
144
|
+
relation.table.create_string_join(Arel.sql(join)) unless join.blank?
|
145
|
+
end.compact
|
146
|
+
|
147
|
+
join_list = join_nodes + joins
|
148
|
+
|
149
|
+
alias_tracker = Associations::AliasTracker.create(relation.klass.connection, relation.table.name, join_list)
|
150
|
+
if BabySqueel::ActiveRecord::VersionHelper.at_least_6_0?
|
151
|
+
join_dependency = Associations::JoinDependency.new(relation.klass, relation.table, association_joins, Arel::Nodes::InnerJoin)
|
152
|
+
join_dependency.instance_variable_set(:@alias_tracker, alias_tracker)
|
153
|
+
elsif BabySqueel::ActiveRecord::VersionHelper.at_least_5_2_3?
|
154
|
+
join_dependency = Associations::JoinDependency.new(relation.klass, relation.table, association_joins)
|
155
|
+
join_dependency.instance_variable_set(:@alias_tracker, alias_tracker)
|
156
|
+
else
|
157
|
+
# Rails 5.2.0 - 5.2.2
|
158
|
+
join_dependency = Associations::JoinDependency.new(relation.klass, relation.table, association_joins, alias_tracker)
|
159
|
+
end
|
160
|
+
join_nodes.each do |join|
|
161
|
+
join_dependency.send(:alias_tracker).aliases[join.left.name.downcase] = 1
|
162
|
+
end
|
163
|
+
|
164
|
+
join_dependency
|
165
|
+
end
|
62
166
|
end
|
63
167
|
end
|
64
168
|
end
|
data/lib/baby_squeel/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: baby_squeel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.4
|
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: 2022-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '5.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '7.1'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '5.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '7.1'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: ransack
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,20 +44,6 @@ dependencies:
|
|
38
44
|
- - "~>"
|
39
45
|
- !ruby/object:Gem::Version
|
40
46
|
version: '2.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.4
|
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.4
|
55
47
|
- !ruby/object:Gem::Dependency
|
56
48
|
name: bundler
|
57
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,16 +90,16 @@ dependencies:
|
|
98
90
|
name: sqlite3
|
99
91
|
requirement: !ruby/object:Gem::Requirement
|
100
92
|
requirements:
|
101
|
-
- - "
|
93
|
+
- - ">="
|
102
94
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
95
|
+
version: '0'
|
104
96
|
type: :development
|
105
97
|
prerelease: false
|
106
98
|
version_requirements: !ruby/object:Gem::Requirement
|
107
99
|
requirements:
|
108
|
-
- - "
|
100
|
+
- - ">="
|
109
101
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
102
|
+
version: '0'
|
111
103
|
description: An expressive query DSL for Active Record 4 and 5.
|
112
104
|
email:
|
113
105
|
- ray@promptworks.com
|
@@ -124,6 +116,7 @@ files:
|
|
124
116
|
- lib/baby_squeel/active_record/base.rb
|
125
117
|
- lib/baby_squeel/active_record/calculations.rb
|
126
118
|
- lib/baby_squeel/active_record/query_methods.rb
|
119
|
+
- lib/baby_squeel/active_record/version_helper.rb
|
127
120
|
- lib/baby_squeel/active_record/where_chain.rb
|
128
121
|
- lib/baby_squeel/association.rb
|
129
122
|
- lib/baby_squeel/calculation.rb
|
@@ -140,7 +133,6 @@ files:
|
|
140
133
|
- lib/baby_squeel/nodes/node.rb
|
141
134
|
- lib/baby_squeel/nodes/proxy.rb
|
142
135
|
- lib/baby_squeel/operators.rb
|
143
|
-
- lib/baby_squeel/pluck.rb
|
144
136
|
- lib/baby_squeel/relation.rb
|
145
137
|
- lib/baby_squeel/resolver.rb
|
146
138
|
- lib/baby_squeel/table.rb
|
@@ -160,11 +152,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
152
|
version: '0'
|
161
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
154
|
requirements:
|
163
|
-
- - "
|
155
|
+
- - ">="
|
164
156
|
- !ruby/object:Gem::Version
|
165
|
-
version:
|
157
|
+
version: '0'
|
166
158
|
requirements: []
|
167
|
-
rubygems_version: 3.
|
159
|
+
rubygems_version: 3.3.3
|
168
160
|
signing_key:
|
169
161
|
specification_version: 4
|
170
162
|
summary: An expressive query DSL for Active Record 4 and 5.
|
data/lib/baby_squeel/pluck.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module BabySqueel
|
2
|
-
class Pluck # :nodoc:
|
3
|
-
# In Active Record 4.2, #pluck chokes when you give it
|
4
|
-
# Arel. It calls #to_s on whatever you pass in. So the
|
5
|
-
# hacky solution is to wrap the node in a class that
|
6
|
-
# returns the node when you call #to_s. Then, it works!
|
7
|
-
#
|
8
|
-
# In Active Record 5, #pluck accepts Arel, so we won't
|
9
|
-
# bother to use this there.
|
10
|
-
|
11
|
-
if ::ActiveRecord::VERSION::MAJOR >= 5
|
12
|
-
def self.decorate(node); node; end
|
13
|
-
else
|
14
|
-
def self.decorate(node); new(node); end
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize(node)
|
18
|
-
@node = node
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_s
|
22
|
-
@node
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|