baby_squeel 1.1.1 → 1.1.2
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.
- checksums.yaml +4 -4
- data/lib/baby_squeel/dsl.rb +2 -6
- data/lib/baby_squeel/errors.rb +13 -2
- data/lib/baby_squeel/join_dependency/builder.rb +16 -1
- data/lib/baby_squeel/relation.rb +3 -13
- data/lib/baby_squeel/resolver.rb +96 -0
- data/lib/baby_squeel/table.rb +6 -10
- data/lib/baby_squeel/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3f4792b9f869cd23c5910a52a2d95188ee75c806
|
|
4
|
+
data.tar.gz: c2d75c755301787ac04d5aa8220396be848f9f28
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6a91030415fc3afd7017e92f89440207bf7069b8f3681a549d3abba3629847e9dd589aabe6398104ff6c89d780660a7f600ddccecd3d69a07decb10fabcbc8f6
|
|
7
|
+
data.tar.gz: 4b1d040212307df0175af66a8e5ce59b7f398abcfae50387a857434d16b06da9b4598ffc3078a42f852272ad2981164f2fde42f3729435a44953d86b1dc17e10
|
data/lib/baby_squeel/dsl.rb
CHANGED
|
@@ -97,12 +97,8 @@ module BabySqueel
|
|
|
97
97
|
|
|
98
98
|
private
|
|
99
99
|
|
|
100
|
-
def
|
|
101
|
-
|
|
102
|
-
func(meth, args)
|
|
103
|
-
else
|
|
104
|
-
super
|
|
105
|
-
end
|
|
100
|
+
def resolver
|
|
101
|
+
@resolver ||= Resolver.new(self, [:function, :column, :association])
|
|
106
102
|
end
|
|
107
103
|
end
|
|
108
104
|
end
|
data/lib/baby_squeel/errors.rb
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
module BabySqueel
|
|
2
2
|
class NotFoundError < StandardError # :nodoc:
|
|
3
|
-
def initialize(model_name, name)
|
|
4
|
-
super "There is no
|
|
3
|
+
def initialize(model_name, name, strategies)
|
|
4
|
+
super "There is no #{sentence(strategies)} " \
|
|
5
|
+
"named '#{name}' for #{model_name}."
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
def sentence(*words)
|
|
11
|
+
if words.length < 3
|
|
12
|
+
words.join ' or '
|
|
13
|
+
else
|
|
14
|
+
sentence words[0..-2].join(', '), words.last
|
|
15
|
+
end
|
|
5
16
|
end
|
|
6
17
|
end
|
|
7
18
|
|
|
@@ -28,7 +28,10 @@ module BabySqueel
|
|
|
28
28
|
def find_join_association(associations)
|
|
29
29
|
associations.inject(join_root) do |parent, assoc|
|
|
30
30
|
parent.children.find do |join_association|
|
|
31
|
-
|
|
31
|
+
reflections_equal?(
|
|
32
|
+
assoc._reflection,
|
|
33
|
+
join_association.reflection
|
|
34
|
+
)
|
|
32
35
|
end
|
|
33
36
|
end
|
|
34
37
|
end
|
|
@@ -43,6 +46,18 @@ module BabySqueel
|
|
|
43
46
|
|
|
44
47
|
private
|
|
45
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
|
+
|
|
46
61
|
# Active Record 5's AliasTracker initializes Arel tables
|
|
47
62
|
# with the type_caster belonging to the wrong model.
|
|
48
63
|
#
|
data/lib/baby_squeel/relation.rb
CHANGED
|
@@ -15,7 +15,7 @@ module BabySqueel
|
|
|
15
15
|
if reflection = _scope.reflect_on_association(name)
|
|
16
16
|
Association.new(self, reflection)
|
|
17
17
|
else
|
|
18
|
-
|
|
18
|
+
raise AssociationNotFoundError.new(_scope.model_name, name)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -30,18 +30,8 @@ module BabySqueel
|
|
|
30
30
|
|
|
31
31
|
private
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
raise type.new(_scope.model_name, name)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# @override BabySqueel::Table#resolve
|
|
39
|
-
def resolve(name)
|
|
40
|
-
if _scope.column_names.include?(name.to_s)
|
|
41
|
-
self[name]
|
|
42
|
-
elsif _scope.reflect_on_association(name)
|
|
43
|
-
association(name)
|
|
44
|
-
end
|
|
33
|
+
def resolver
|
|
34
|
+
@resolver ||= Resolver.new(self, [:column, :association])
|
|
45
35
|
end
|
|
46
36
|
end
|
|
47
37
|
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module BabySqueel
|
|
2
|
+
class Resolver
|
|
3
|
+
def initialize(table, strategies)
|
|
4
|
+
@table = table
|
|
5
|
+
@strategies = strategies
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Attempt to determine the intent of the method_missing. If this method
|
|
9
|
+
# returns nil, that means one of two things:
|
|
10
|
+
#
|
|
11
|
+
# 1. The argument signature is invalid.
|
|
12
|
+
# 2. The name of the method called is not valid (ex. invalid column name)
|
|
13
|
+
def resolve(name, *args, &block)
|
|
14
|
+
strategy = @strategies.find do |strategy|
|
|
15
|
+
valid?(strategy, name, *args, &block)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
build(strategy, name, *args, &block)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Try to resolve the method_missing. If we fail to resolve, there are
|
|
22
|
+
# two outcomes:
|
|
23
|
+
#
|
|
24
|
+
# If any of the configured strategies accept argument signature provided,
|
|
25
|
+
# raise an error. This means we failed to resolve the name. (ex. invalid
|
|
26
|
+
# column name)
|
|
27
|
+
#
|
|
28
|
+
# Otherwise, a nil return valid indicates that argument signature was not
|
|
29
|
+
# valid for any of the configured strategies. This case should be treated
|
|
30
|
+
# as a NoMethodError.
|
|
31
|
+
def resolve!(name, *args, &block)
|
|
32
|
+
if resolution = resolve(name, *args, &block)
|
|
33
|
+
return resolution
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if compatible_arguments?(*args, &block)
|
|
37
|
+
raise NotFoundError.new(@table._scope.model_name, name, @strategies)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
return nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Used to determine if a table can respond_to? a method.
|
|
44
|
+
def resolves?(name)
|
|
45
|
+
@strategies.any? do |strategy|
|
|
46
|
+
valid_name? strategy, name
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def build(strategy, name, *args)
|
|
53
|
+
case strategy
|
|
54
|
+
when :function
|
|
55
|
+
@table.func(name, *args)
|
|
56
|
+
when :association
|
|
57
|
+
@table.association(name)
|
|
58
|
+
when :column, :attribute
|
|
59
|
+
@table[name]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def valid?(strategy, name, *args, &block)
|
|
64
|
+
valid_arguments?(strategy, *args, &block) &&
|
|
65
|
+
valid_name?(strategy, name)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def valid_name?(strategy, name)
|
|
69
|
+
case strategy
|
|
70
|
+
when :column
|
|
71
|
+
@table._scope.column_names.include?(name.to_s)
|
|
72
|
+
when :association
|
|
73
|
+
!@table._scope.reflect_on_association(name).nil?
|
|
74
|
+
when :function, :attribute
|
|
75
|
+
true
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def valid_arguments?(strategy, *args)
|
|
80
|
+
return false if block_given?
|
|
81
|
+
|
|
82
|
+
case strategy
|
|
83
|
+
when :function
|
|
84
|
+
!args.empty?
|
|
85
|
+
when :column, :attribute, :association
|
|
86
|
+
args.empty?
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def compatible_arguments?(*args, &block)
|
|
91
|
+
@strategies.any? do |strategy|
|
|
92
|
+
valid_arguments?(strategy, *args, &block)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
data/lib/baby_squeel/table.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'baby_squeel/resolver'
|
|
1
2
|
require 'baby_squeel/join_expression'
|
|
2
3
|
require 'baby_squeel/join_dependency/builder'
|
|
3
4
|
|
|
@@ -93,21 +94,16 @@ module BabySqueel
|
|
|
93
94
|
|
|
94
95
|
private
|
|
95
96
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def resolve(name)
|
|
101
|
-
self[name]
|
|
97
|
+
def resolver
|
|
98
|
+
@resolver ||= Resolver.new(self, [:attribute])
|
|
102
99
|
end
|
|
103
100
|
|
|
104
101
|
def respond_to_missing?(name, *)
|
|
105
|
-
|
|
102
|
+
resolver.resolves?(name) || super
|
|
106
103
|
end
|
|
107
104
|
|
|
108
|
-
def method_missing(
|
|
109
|
-
|
|
110
|
-
resolve(name) || not_found_error!(name)
|
|
105
|
+
def method_missing(*args, &block)
|
|
106
|
+
resolver.resolve!(*args, &block) || super
|
|
111
107
|
end
|
|
112
108
|
end
|
|
113
109
|
end
|
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.1.
|
|
4
|
+
version: 1.1.2
|
|
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-
|
|
11
|
+
date: 2017-03-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -129,6 +129,7 @@ files:
|
|
|
129
129
|
- lib/baby_squeel/operators.rb
|
|
130
130
|
- lib/baby_squeel/pluck.rb
|
|
131
131
|
- lib/baby_squeel/relation.rb
|
|
132
|
+
- lib/baby_squeel/resolver.rb
|
|
132
133
|
- lib/baby_squeel/table.rb
|
|
133
134
|
- lib/baby_squeel/version.rb
|
|
134
135
|
homepage: https://github.com/rzane/baby_squeel
|
|
@@ -151,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
151
152
|
version: '0'
|
|
152
153
|
requirements: []
|
|
153
154
|
rubyforge_project:
|
|
154
|
-
rubygems_version: 2.
|
|
155
|
+
rubygems_version: 2.6.10
|
|
155
156
|
signing_key:
|
|
156
157
|
specification_version: 4
|
|
157
158
|
summary: An expressive query DSL for Active Record 4 and 5.
|