squeel 0.7.6 → 0.8.0
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.
- data/README.md +16 -4
- data/lib/squeel/version.rb +1 -1
- data/lib/squeel/visitors/predicate_visitor.rb +14 -1
- data/spec/squeel/visitors/predicate_visitor_spec.rb +18 -0
- metadata +13 -13
data/README.md
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
# Squeel
|
|
2
2
|
|
|
3
|
-
Squeel
|
|
3
|
+
Squeel lets you write your ActiveRecord queries with with fewer strings, and more Ruby,
|
|
4
|
+
by making the ARel awesomeness that lies beneath ActiveRecord more accessible.
|
|
5
|
+
|
|
6
|
+
Squeel lets you rewrite...
|
|
7
|
+
|
|
8
|
+
Article.where ['created_at >= ?', 2.weeks.ago]
|
|
9
|
+
|
|
10
|
+
...as...
|
|
11
|
+
|
|
12
|
+
Article.where{created_at >= 2.weeks.ago}
|
|
13
|
+
|
|
14
|
+
This is a _good thing_. If you don't agree, Squeel might not be for you. The above is
|
|
15
|
+
just a simple example -- Squeel's capable of a whole lot more. Keep reading.
|
|
4
16
|
|
|
5
17
|
## Getting started
|
|
6
18
|
|
|
@@ -9,7 +21,7 @@ In your Gemfile:
|
|
|
9
21
|
gem "squeel" # Last officially released gem
|
|
10
22
|
# gem "squeel", :git => "git://github.com/ernie/squeel.git" # Track git repo
|
|
11
23
|
|
|
12
|
-
In an
|
|
24
|
+
In an initializer:
|
|
13
25
|
|
|
14
26
|
Squeel.configure do |config|
|
|
15
27
|
# To load hash extensions (to allow for AND (&), OR (|), and NOT (-) against
|
|
@@ -34,7 +46,7 @@ Stubs and keypaths are the two primary building blocks used in a Squeel DSL quer
|
|
|
34
46
|
start by taking a look at them. Most of the other examples that follow will be based on
|
|
35
47
|
this "symbol-less" block syntax.
|
|
36
48
|
|
|
37
|
-
|
|
49
|
+
**An important gotcha, before we begin:** The Squeel DSL works its magic using `instance_eval`.
|
|
38
50
|
If you've been working with Ruby for a while, you'll know immediately that this means that
|
|
39
51
|
_inside_ a Squeel DSL block, `self` isn't the same thing that it is _outside_ the block.
|
|
40
52
|
|
|
@@ -46,7 +58,7 @@ to your object's methods and variables:
|
|
|
46
58
|
|
|
47
59
|
1. Assign the variable locally before the DSL block, and access it as you would
|
|
48
60
|
normally.
|
|
49
|
-
2. Supply an arity to the DSL block, as in `Person.where{|
|
|
61
|
+
2. Supply an arity to the DSL block, as in `Person.where{|q| q.name == @my_name}`
|
|
50
62
|
Downside: You'll need to prefix stubs, keypaths, and functions (explained below)
|
|
51
63
|
with the DSL object.
|
|
52
64
|
3. Wrap the method or instance variable inside the block with `my{}`.
|
data/lib/squeel/version.rb
CHANGED
|
@@ -4,6 +4,9 @@ module Squeel
|
|
|
4
4
|
module Visitors
|
|
5
5
|
class PredicateVisitor < Base
|
|
6
6
|
|
|
7
|
+
TRUE_SQL = Arel.sql('1=1').freeze
|
|
8
|
+
FALSE_SQL = Arel.sql('1=0').freeze
|
|
9
|
+
|
|
7
10
|
private
|
|
8
11
|
|
|
9
12
|
# Visit a Hash. This entails iterating through each key and value and
|
|
@@ -79,6 +82,12 @@ module Squeel
|
|
|
79
82
|
# (Arel::Nodes::Equality, Arel::Nodes::Matches, etc)
|
|
80
83
|
def visit_Squeel_Nodes_Predicate(o, parent)
|
|
81
84
|
value = o.value
|
|
85
|
+
|
|
86
|
+
if Array === value && value.empty? && [:in, :not_in].include?(o.method_name)
|
|
87
|
+
# Special case, in/not_in with empty arrays should be false/true respectively
|
|
88
|
+
return o.method_name == :in ? FALSE_SQL : TRUE_SQL
|
|
89
|
+
end
|
|
90
|
+
|
|
82
91
|
if Nodes::KeyPath === value
|
|
83
92
|
value = can_accept?(value.endpoint) ? accept(value, parent) : contextualize(traverse(value, parent))[value.endpoint.to_sym]
|
|
84
93
|
else
|
|
@@ -274,7 +283,11 @@ module Squeel
|
|
|
274
283
|
def arel_predicate_for(attribute, value, parent)
|
|
275
284
|
value = can_accept?(value) ? accept(value, parent) : value
|
|
276
285
|
if [Array, Range, Arel::SelectManager].include?(value.class)
|
|
277
|
-
|
|
286
|
+
if Array === value && value.empty?
|
|
287
|
+
FALSE_SQL
|
|
288
|
+
else
|
|
289
|
+
attribute.in(value)
|
|
290
|
+
end
|
|
278
291
|
else
|
|
279
292
|
attribute.eq(value)
|
|
280
293
|
end
|
|
@@ -37,6 +37,24 @@ module Squeel
|
|
|
37
37
|
predicate.right.should eq ['Joe', 'Bob']
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
it 'generates "1=0" when given an empty array value in a hash' do
|
|
41
|
+
predicate = @v.accept(:id => [])
|
|
42
|
+
predicate.should be_a Arel::Nodes::SqlLiteral
|
|
43
|
+
predicate.should eq '1=0'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'generates "1=0" for in predicates when given an empty array value' do
|
|
47
|
+
predicate = @v.accept(:id.in => [])
|
|
48
|
+
predicate.should be_a Arel::Nodes::SqlLiteral
|
|
49
|
+
predicate.should eq '1=0'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'generates "1=1" for not_in predicates when given an empty array value' do
|
|
53
|
+
predicate = @v.accept(:id.not_in => [])
|
|
54
|
+
predicate.should be_a Arel::Nodes::SqlLiteral
|
|
55
|
+
predicate.should eq '1=1'
|
|
56
|
+
end
|
|
57
|
+
|
|
40
58
|
it 'allows a subquery on the value side of an explicit predicate' do
|
|
41
59
|
predicate = @v.accept dsl{name.in(Person.select{name}.where{name.in(['Aric Smith', 'Gladyce Kulas'])})}
|
|
42
60
|
predicate.should be_a Arel::Nodes::In
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: squeel
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -13,7 +13,7 @@ date: 2011-06-13 00:00:00.000000000Z
|
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activerecord
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &2153399220 !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ~>
|
|
@@ -21,10 +21,10 @@ dependencies:
|
|
|
21
21
|
version: '3.0'
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *2153399220
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
26
26
|
name: activesupport
|
|
27
|
-
requirement: &
|
|
27
|
+
requirement: &2153398720 !ruby/object:Gem::Requirement
|
|
28
28
|
none: false
|
|
29
29
|
requirements:
|
|
30
30
|
- - ~>
|
|
@@ -32,10 +32,10 @@ dependencies:
|
|
|
32
32
|
version: '3.0'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
35
|
+
version_requirements: *2153398720
|
|
36
36
|
- !ruby/object:Gem::Dependency
|
|
37
37
|
name: rspec
|
|
38
|
-
requirement: &
|
|
38
|
+
requirement: &2153398260 !ruby/object:Gem::Requirement
|
|
39
39
|
none: false
|
|
40
40
|
requirements:
|
|
41
41
|
- - ~>
|
|
@@ -43,10 +43,10 @@ dependencies:
|
|
|
43
43
|
version: 2.5.0
|
|
44
44
|
type: :development
|
|
45
45
|
prerelease: false
|
|
46
|
-
version_requirements: *
|
|
46
|
+
version_requirements: *2153398260
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
48
|
name: machinist
|
|
49
|
-
requirement: &
|
|
49
|
+
requirement: &2153397780 !ruby/object:Gem::Requirement
|
|
50
50
|
none: false
|
|
51
51
|
requirements:
|
|
52
52
|
- - ~>
|
|
@@ -54,10 +54,10 @@ dependencies:
|
|
|
54
54
|
version: 1.0.6
|
|
55
55
|
type: :development
|
|
56
56
|
prerelease: false
|
|
57
|
-
version_requirements: *
|
|
57
|
+
version_requirements: *2153397780
|
|
58
58
|
- !ruby/object:Gem::Dependency
|
|
59
59
|
name: faker
|
|
60
|
-
requirement: &
|
|
60
|
+
requirement: &2153397280 !ruby/object:Gem::Requirement
|
|
61
61
|
none: false
|
|
62
62
|
requirements:
|
|
63
63
|
- - ~>
|
|
@@ -65,10 +65,10 @@ dependencies:
|
|
|
65
65
|
version: 0.9.5
|
|
66
66
|
type: :development
|
|
67
67
|
prerelease: false
|
|
68
|
-
version_requirements: *
|
|
68
|
+
version_requirements: *2153397280
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: sqlite3
|
|
71
|
-
requirement: &
|
|
71
|
+
requirement: &2153396780 !ruby/object:Gem::Requirement
|
|
72
72
|
none: false
|
|
73
73
|
requirements:
|
|
74
74
|
- - ~>
|
|
@@ -76,7 +76,7 @@ dependencies:
|
|
|
76
76
|
version: 1.3.3
|
|
77
77
|
type: :development
|
|
78
78
|
prerelease: false
|
|
79
|
-
version_requirements: *
|
|
79
|
+
version_requirements: *2153396780
|
|
80
80
|
description: ! "\n Squeel unlocks the power of ARel in your Rails 3 application
|
|
81
81
|
with\n a handy block-based syntax. You can write subqueries, access named\n
|
|
82
82
|
\ functions provided by your RDBMS, and more, all without writing\n SQL
|