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 CHANGED
@@ -1,6 +1,18 @@
1
1
  # Squeel
2
2
 
3
- Squeel is a rewrite of [MetaWhere](http://metautonomo.us/projects/metawhere).
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 intitializer:
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
- *An important gotcha, before we begin:* The Squeel DSL works its magic using `instance_eval`.
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{|dsl| dsl.name == @my_name}`
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{}`.
@@ -1,3 +1,3 @@
1
1
  module Squeel
2
- VERSION = "0.7.6"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -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
- attribute.in(value)
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.7.6
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: &2156244960 !ruby/object:Gem::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: *2156244960
24
+ version_requirements: *2153399220
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &2156244220 !ruby/object:Gem::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: *2156244220
35
+ version_requirements: *2153398720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &2156242240 !ruby/object:Gem::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: *2156242240
46
+ version_requirements: *2153398260
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: machinist
49
- requirement: &2156236780 !ruby/object:Gem::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: *2156236780
57
+ version_requirements: *2153397780
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: faker
60
- requirement: &2156197500 !ruby/object:Gem::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: *2156197500
68
+ version_requirements: *2153397280
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sqlite3
71
- requirement: &2156196800 !ruby/object:Gem::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: *2156196800
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