squeel 0.9.5 → 1.0.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/.travis.yml CHANGED
@@ -1,10 +1,13 @@
1
1
  rvm:
2
2
  - 1.8.7
3
- - 1.9.2
4
3
  - 1.9.3
5
- - ree
6
- - rbx
7
- - ruby-head
4
+ # TODO: Re-enable when updates to Rubinius on
5
+ # Travis stop randomly breaking specs that
6
+ # pass on MRI. :(
7
+ # - rbx-18mode
8
+ # - rbx-19mode
8
9
 
9
10
  env:
10
11
  - RAILS=3-2-stable
12
+ - RAILS=3-1-stable AREL=2-2-stable
13
+ - RAILS=3-0-stable AREL=2-0-stable
data/Gemfile CHANGED
@@ -34,4 +34,4 @@ else
34
34
  gem 'activemodel'
35
35
  gem 'activerecord'
36
36
  end
37
- end
37
+ end
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Squeel [![Build Status](https://secure.travis-ci.org/ernie/squeel.png)](http://travis-ci.org/ernie/squeel)
2
2
 
3
- Squeel lets you write your ActiveRecord queries with with fewer strings, and more Ruby,
3
+ Squeel lets you write your ActiveRecord queries with fewer strings, and more Ruby,
4
4
  by making the ARel awesomeness that lies beneath ActiveRecord more accessible.
5
5
 
6
6
  Squeel lets you rewrite...
@@ -21,20 +21,13 @@ In your Gemfile:
21
21
  gem "squeel" # Last officially released gem
22
22
  # gem "squeel", :git => "git://github.com/ernie/squeel.git" # Track git repo
23
23
 
24
- In an initializer:
24
+ Then bundle as usual.
25
25
 
26
- Squeel.configure do |config|
27
- # To load hash extensions (to allow for AND (&), OR (|), and NOT (-) against
28
- # hashes of conditions)
29
- config.load_core_extensions :hash
30
-
31
- # To load symbol extensions (for a subset of the old MetaWhere functionality,
32
- # via ARel predicate methods on Symbols: :name.matches, etc)
33
- # config.load_core_extensions :symbol
26
+ If you'd like to customize Squeel's functionality by enabling core
27
+ extensions for hashes or symbols, or aliasing some predicates, you can
28
+ create a sample initializer with:
34
29
 
35
- # To load both hash and symbol extensions
36
- # config.load_core_extensions :hash, :symbol
37
- end
30
+ rails g squeel:initializer
38
31
 
39
32
  ## The Squeel Query DSL
40
33
 
@@ -443,4 +436,4 @@ To support the project in other ways:
443
436
 
444
437
  ## Copyright
445
438
 
446
- Copyright © 2011 [Ernie Miller](http://twitter.com/erniemiller)
439
+ Copyright © 2011 [Ernie Miller](http://twitter.com/erniemiller)
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- require 'bundler'
1
+ require 'bundler/setup'
2
2
  require 'rspec/core/rake_task'
3
3
 
4
4
  Bundler::GemHelper.install_tasks
@@ -16,4 +16,4 @@ task :console do
16
16
  require 'console'
17
17
  ARGV.clear
18
18
  IRB.start
19
- end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Squeel
2
+ module Generators
3
+ class InitializerGenerator < ::Rails::Generators::Base
4
+
5
+ source_root File.expand_path("../../templates", __FILE__)
6
+
7
+ desc 'Creates a sample Squeel initializer.'
8
+
9
+ def copy_initializer
10
+ copy_file 'squeel.rb', 'config/initializers/squeel.rb'
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ Squeel.configure do |config|
2
+ # To load hash extensions (to allow for AND (&), OR (|), and NOT (-) against
3
+ # hashes of conditions):
4
+ #
5
+ # config.load_core_extensions :hash
6
+
7
+ # To load symbol extensions (for a subset of the old MetaWhere functionality,
8
+ # via ARel predicate methods on Symbols: :name.matches, etc):
9
+ #
10
+ # NOTE: Not recommended. Learn the new DSL. Use it. Love it.
11
+ #
12
+ # config.load_core_extensions :symbol
13
+
14
+ # To load both hash and symbol extensions:
15
+ #
16
+ # config.load_core_extensions :hash, :symbol
17
+
18
+ # Alias an existing predicate to a new name. Use the non-grouped
19
+ # name -- the any/all variants will also be created. For example,
20
+ # to alias the standard "lt" predicate to "less_than", and gain
21
+ # "less_than_any" and "less_than_all" as well:
22
+ #
23
+ # config.alias_predicate :less_than, :lt
24
+ end
@@ -106,6 +106,35 @@ module Squeel
106
106
  arel
107
107
  end
108
108
 
109
+ # So, building a select for a count query in ActiveRecord is
110
+ # pretty heavily dependent on select_values containing strings.
111
+ # I'd initially expected that I could just hack together a fix
112
+ # to select_for_count and everything would fall in line, but
113
+ # unfortunately, pretty much everything from that point on
114
+ # in ActiveRecord::Calculations#perform_calculation expects
115
+ # the column to be a string, or at worst, a symbol.
116
+ #
117
+ # In the long term, I would like to refactor the code in
118
+ # Rails core, but for now, I'm going to settle for this hack
119
+ # that tries really hard to coerce things to a string.
120
+ def select_for_count
121
+ visited_values = attribute_visitor.accept(select_values.uniq)
122
+ if visited_values.size == 1
123
+ select = visited_values.first
124
+
125
+ str_select = case select
126
+ when String
127
+ select
128
+ when Symbol
129
+ select.to_s
130
+ else
131
+ select.to_sql if select.respond_to?(:to_sql)
132
+ end
133
+
134
+ str_select if str_select && str_select !~ /[,*]/
135
+ end
136
+ end
137
+
109
138
  def build_join_dependency(relation, joins)
110
139
  association_joins = []
111
140
 
@@ -336,4 +365,4 @@ module Squeel
336
365
  end
337
366
  end
338
367
  end
339
- end
368
+ end
@@ -117,6 +117,35 @@ module Squeel
117
117
  end
118
118
  end
119
119
 
120
+ # So, building a select for a count query in ActiveRecord is
121
+ # pretty heavily dependent on select_values containing strings.
122
+ # I'd initially expected that I could just hack together a fix
123
+ # to select_for_count and everything would fall in line, but
124
+ # unfortunately, pretty much everything from that point on
125
+ # in ActiveRecord::Calculations#perform_calculation expects
126
+ # the column to be a string, or at worst, a symbol.
127
+ #
128
+ # In the long term, I would like to refactor the code in
129
+ # Rails core, but for now, I'm going to settle for this hack
130
+ # that tries really hard to coerce things to a string.
131
+ def select_for_count
132
+ visited_values = attribute_visitor.accept(select_values.uniq)
133
+ if visited_values.size == 1
134
+ select = visited_values.first
135
+
136
+ str_select = case select
137
+ when String
138
+ select
139
+ when Symbol
140
+ select.to_s
141
+ else
142
+ select.to_sql if select.respond_to?(:to_sql)
143
+ end
144
+
145
+ str_select if str_select && str_select !~ /[,*]/
146
+ end
147
+ end
148
+
120
149
  def build_join_dependency(manager, joins)
121
150
  buckets = joins.group_by do |join|
122
151
  case join
@@ -344,7 +373,7 @@ module Squeel
344
373
  end
345
374
 
346
375
  def where_values_hash_with_squeel
347
- equalities = find_equality_predicates(predicate_visitor.accept(@where_values))
376
+ equalities = find_equality_predicates(predicate_visitor.accept(with_default_scope.where_values))
348
377
 
349
378
  Hash[equalities.map { |where| [where.left.name, where.right] }]
350
379
  end
@@ -352,4 +381,4 @@ module Squeel
352
381
  end
353
382
  end
354
383
  end
355
- end
384
+ end
@@ -6,6 +6,7 @@ module Squeel
6
6
  class Function
7
7
 
8
8
  include PredicateMethods
9
+ include PredicateOperators
9
10
  include Operators
10
11
 
11
12
  alias :== :eq
@@ -63,4 +64,4 @@ module Squeel
63
64
 
64
65
  end
65
66
  end
66
- end
67
+ end
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/module'
2
+
1
3
  module Squeel
2
4
  module Nodes
3
5
  # A node representing a joined association
@@ -83,4 +85,4 @@ module Squeel
83
85
 
84
86
  end
85
87
  end
86
- end
88
+ end
@@ -1,5 +1,6 @@
1
1
  require 'squeel/nodes/operators'
2
2
  require 'squeel/nodes/predicate_operators'
3
+ require 'active_support/core_ext/module'
3
4
 
4
5
  module Squeel
5
6
  module Nodes
@@ -204,4 +205,4 @@ module Squeel
204
205
 
205
206
  end
206
207
  end
207
- end
208
+ end
@@ -1,3 +1,3 @@
1
1
  module Squeel
2
- VERSION = "0.9.5"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -108,6 +108,13 @@ module Squeel
108
108
  arel.to_sql.should match /"people"."name" LIKE '%bob%'/
109
109
  end
110
110
 
111
+ it 'handles multiple wheres using a keypath' do
112
+ relation = Person.joins{articles}.where{articles.title == 'Hello'}.
113
+ where{articles.body == 'World'}
114
+ arel = relation.build_arel
115
+ arel.to_sql.should match /articles/
116
+ end
117
+
111
118
  it 'maps wheres inside a hash to their appropriate association table' do
112
119
  relation = Person.joins({
113
120
  :children => {
@@ -394,6 +401,10 @@ module Squeel
394
401
  aric.last_article_id.should eq Article.where(:person_id => 1).last.id
395
402
  end
396
403
 
404
+ it "doesn't break #count if non-strings are used" do
405
+ Article.select{distinct(title)}.count.should eq 51
406
+ end
407
+
397
408
  end
398
409
 
399
410
  describe '#group' do
@@ -477,7 +488,7 @@ module Squeel
477
488
  relation = Person.joins(:authored_article_comments)
478
489
  relation.first.authored_article_comments.first.should eq Comment.first
479
490
  end
480
-
491
+
481
492
  it 'creates a unique join when joining a table used in a has_many :through association' do
482
493
  Person.first.authored_article_comments.joins(:article).first.should eq Comment.first
483
494
  end
@@ -597,6 +608,10 @@ module Squeel
597
608
  @person.name.should eq 'bob'
598
609
  end
599
610
 
611
+ it "maintains activerecord default scope functionality" do
612
+ PersonNamedBill.new.name.should eq 'Bill'
613
+ end
614
+
600
615
  it 'uses the last supplied equality predicate in where_values when creating new records' do
601
616
  @person = Person.where(:name => 'bob', :parent_id => 3).where(:name => 'joe').new
602
617
  @person.parent_id.should eq 3
@@ -674,7 +689,9 @@ module Squeel
674
689
 
675
690
  queries.should have(2).queries
676
691
 
677
- queries.last.should match /IN \(1, ?34, ?67, ?100\)/
692
+ matched_ids = queries.last.match(/IN \(([^)]*)/).captures.first
693
+ matched_ids = matched_ids.split(/,\s*/).map(&:to_i)
694
+ matched_ids.should =~ [1, 34, 67, 100]
678
695
  end
679
696
 
680
697
  end
@@ -682,4 +699,4 @@ module Squeel
682
699
  end
683
700
  end
684
701
  end
685
- end
702
+ end
@@ -4,7 +4,7 @@ module Squeel
4
4
  module Nodes
5
5
  describe Function do
6
6
  before do
7
- @f = :function.func(1,2,3)
7
+ @f = Function.new(:function, [1, 2, 3])
8
8
  end
9
9
 
10
10
  Squeel::Constants::PREDICATES.each do |method_name|
@@ -132,6 +132,27 @@ module Squeel
132
132
  predicate.value.should eq 1
133
133
  end
134
134
 
135
+ it 'can be ORed with another node' do
136
+ right = Predicate.new :name, :eq, 'Bob'
137
+ combined = @f | right
138
+ combined.should be_a Nodes::Or
139
+ combined.left.should eq @f
140
+ combined.right.should eq right
141
+ end
142
+
143
+ it 'can be ANDed with another node' do
144
+ right = Predicate.new :name, :eq, 'Bob'
145
+ combined = @f & right
146
+ combined.should be_a Nodes::And
147
+ combined.children.should eq [@f, right]
148
+ end
149
+
150
+ it 'can be negated' do
151
+ negated = -@f
152
+ negated.should be_a Nodes::Not
153
+ negated.expr.should eq @f
154
+ end
155
+
135
156
  describe '#as' do
136
157
 
137
158
  it 'aliases the function' do
@@ -148,4 +169,4 @@ module Squeel
148
169
 
149
170
  end
150
171
  end
151
- end
172
+ end
@@ -132,6 +132,27 @@ module Squeel
132
132
  predicate.value.should eq 1
133
133
  end
134
134
 
135
+ it 'can be ORed with another node' do
136
+ right = Predicate.new :name, :eq, 'Bob'
137
+ combined = @o | right
138
+ combined.should be_a Nodes::Or
139
+ combined.left.should eq @o
140
+ combined.right.should eq right
141
+ end
142
+
143
+ it 'can be ANDed with another node' do
144
+ right = Predicate.new :name, :eq, 'Bob'
145
+ combined = @o & right
146
+ combined.should be_a Nodes::And
147
+ combined.children.should eq [@o, right]
148
+ end
149
+
150
+ it 'can be negated' do
151
+ negated = -@o
152
+ negated.should be_a Nodes::Not
153
+ negated.expr.should eq @o
154
+ end
155
+
135
156
  describe '#as' do
136
157
 
137
158
  it 'aliases the function' do
@@ -148,4 +169,4 @@ module Squeel
148
169
 
149
170
  end
150
171
  end
151
- end
172
+ end
@@ -33,6 +33,11 @@ class PersonWithNamePrimaryKey < ActiveRecord::Base
33
33
  set_table_name 'people'
34
34
  end
35
35
 
36
+ class PersonNamedBill < ActiveRecord::Base
37
+ self.table_name = 'people'
38
+ default_scope where(:name => 'Bill')
39
+ end
40
+
36
41
  class Message < ActiveRecord::Base
37
42
  belongs_to :author, :class_name => 'Person'
38
43
  belongs_to :recipient, :class_name => 'Person'
@@ -141,4 +146,4 @@ module Schema
141
146
  Comment.make(:body => 'Last post!', :article => Article.first, :person => Article.first.commenters.first)
142
147
 
143
148
  end
144
- end
149
+ end
data/squeel.gemspec CHANGED
@@ -7,8 +7,8 @@ Gem::Specification.new do |s|
7
7
  s.version = Squeel::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Ernie Miller"]
10
- s.email = ["ernie@metautonomo.us"]
11
- s.homepage = "http://metautonomo.us/projects/squeel"
10
+ s.email = ["ernie@erniemiller.org"]
11
+ s.homepage = "http://erniemiller.org/projects/squeel"
12
12
  s.summary = %q{ActiveRecord 3, improved.}
13
13
  s.description = %q{
14
14
  Squeel unlocks the power of ARel in your Rails 3 application with
@@ -16,15 +16,6 @@ Gem::Specification.new do |s|
16
16
  functions provided by your RDBMS, and more, all without writing
17
17
  SQL strings.
18
18
  }
19
- s.post_install_message = %q{
20
- *** Thanks for installing Squeel! ***
21
- Be sure to check out http://metautonomo.us/projects/squeel/ for a
22
- walkthrough of Squeel's features, and click the donate link if
23
- you're feeling especially appreciative. It'd help me justify this
24
- "open source" stuff to my lovely wife. :)
25
-
26
- }
27
-
28
19
  s.rubyforge_project = "squeel"
29
20
 
30
21
  s.add_dependency 'activerecord', '~> 3.0'
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.9.5
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-23 00:00:00.000000000 Z
12
+ date: 2012-04-22 00:00:00.000000000 -04:00
13
+ default_executable:
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: activerecord
16
- requirement: &70289249898780 !ruby/object:Gem::Requirement
17
+ requirement: &70321134916300 !ruby/object:Gem::Requirement
17
18
  none: false
18
19
  requirements:
19
20
  - - ~>
@@ -21,10 +22,10 @@ dependencies:
21
22
  version: '3.0'
22
23
  type: :runtime
23
24
  prerelease: false
24
- version_requirements: *70289249898780
25
+ version_requirements: *70321134916300
25
26
  - !ruby/object:Gem::Dependency
26
27
  name: activesupport
27
- requirement: &70289249898020 !ruby/object:Gem::Requirement
28
+ requirement: &70321134915080 !ruby/object:Gem::Requirement
28
29
  none: false
29
30
  requirements:
30
31
  - - ~>
@@ -32,10 +33,10 @@ dependencies:
32
33
  version: '3.0'
33
34
  type: :runtime
34
35
  prerelease: false
35
- version_requirements: *70289249898020
36
+ version_requirements: *70321134915080
36
37
  - !ruby/object:Gem::Dependency
37
38
  name: polyamorous
38
- requirement: &70289249897260 !ruby/object:Gem::Requirement
39
+ requirement: &70321134914020 !ruby/object:Gem::Requirement
39
40
  none: false
40
41
  requirements:
41
42
  - - ~>
@@ -43,10 +44,10 @@ dependencies:
43
44
  version: 0.5.0
44
45
  type: :runtime
45
46
  prerelease: false
46
- version_requirements: *70289249897260
47
+ version_requirements: *70321134914020
47
48
  - !ruby/object:Gem::Dependency
48
49
  name: rspec
49
- requirement: &70289249896240 !ruby/object:Gem::Requirement
50
+ requirement: &70321134911960 !ruby/object:Gem::Requirement
50
51
  none: false
51
52
  requirements:
52
53
  - - ~>
@@ -54,10 +55,10 @@ dependencies:
54
55
  version: 2.6.0
55
56
  type: :development
56
57
  prerelease: false
57
- version_requirements: *70289249896240
58
+ version_requirements: *70321134911960
58
59
  - !ruby/object:Gem::Dependency
59
60
  name: machinist
60
- requirement: &70289249894040 !ruby/object:Gem::Requirement
61
+ requirement: &70321134928680 !ruby/object:Gem::Requirement
61
62
  none: false
62
63
  requirements:
63
64
  - - ~>
@@ -65,10 +66,10 @@ dependencies:
65
66
  version: 1.0.6
66
67
  type: :development
67
68
  prerelease: false
68
- version_requirements: *70289249894040
69
+ version_requirements: *70321134928680
69
70
  - !ruby/object:Gem::Dependency
70
71
  name: faker
71
- requirement: &70289249893140 !ruby/object:Gem::Requirement
72
+ requirement: &70321134927360 !ruby/object:Gem::Requirement
72
73
  none: false
73
74
  requirements:
74
75
  - - ~>
@@ -76,10 +77,10 @@ dependencies:
76
77
  version: 0.9.5
77
78
  type: :development
78
79
  prerelease: false
79
- version_requirements: *70289249893140
80
+ version_requirements: *70321134927360
80
81
  - !ruby/object:Gem::Dependency
81
82
  name: sqlite3
82
- requirement: &70289249892520 !ruby/object:Gem::Requirement
83
+ requirement: &70321134925640 !ruby/object:Gem::Requirement
83
84
  none: false
84
85
  requirements:
85
86
  - - ~>
@@ -87,13 +88,13 @@ dependencies:
87
88
  version: 1.3.3
88
89
  type: :development
89
90
  prerelease: false
90
- version_requirements: *70289249892520
91
+ version_requirements: *70321134925640
91
92
  description: ! "\n Squeel unlocks the power of ARel in your Rails 3 application
92
93
  with\n a handy block-based syntax. You can write subqueries, access named\n
93
94
  \ functions provided by your RDBMS, and more, all without writing\n SQL
94
95
  strings.\n "
95
96
  email:
96
- - ernie@metautonomo.us
97
+ - ernie@erniemiller.org
97
98
  executables: []
98
99
  extensions: []
99
100
  extra_rdoc_files: []
@@ -105,6 +106,8 @@ files:
105
106
  - LICENSE
106
107
  - README.md
107
108
  - Rakefile
109
+ - lib/generators/squeel/initializer_generator.rb
110
+ - lib/generators/templates/squeel.rb
108
111
  - lib/squeel.rb
109
112
  - lib/squeel/adapters/active_record.rb
110
113
  - lib/squeel/adapters/active_record/3.0/association_preload_extensions.rb
@@ -183,22 +186,10 @@ files:
183
186
  - spec/squeel/visitors/symbol_visitor_spec.rb
184
187
  - spec/support/schema.rb
185
188
  - squeel.gemspec
186
- homepage: http://metautonomo.us/projects/squeel
189
+ has_rdoc: true
190
+ homepage: http://erniemiller.org/projects/squeel
187
191
  licenses: []
188
- post_install_message: ! '
189
-
190
- *** Thanks for installing Squeel! ***
191
-
192
- Be sure to check out http://metautonomo.us/projects/squeel/ for a
193
-
194
- walkthrough of Squeel''s features, and click the donate link if
195
-
196
- you''re feeling especially appreciative. It''d help me justify this
197
-
198
- "open source" stuff to my lovely wife. :)
199
-
200
-
201
- '
192
+ post_install_message:
202
193
  rdoc_options: []
203
194
  require_paths:
204
195
  - lib
@@ -208,15 +199,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
208
199
  - - ! '>='
209
200
  - !ruby/object:Gem::Version
210
201
  version: '0'
202
+ segments:
203
+ - 0
204
+ hash: -1688941417700106629
211
205
  required_rubygems_version: !ruby/object:Gem::Requirement
212
206
  none: false
213
207
  requirements:
214
208
  - - ! '>='
215
209
  - !ruby/object:Gem::Version
216
210
  version: '0'
211
+ segments:
212
+ - 0
213
+ hash: -1688941417700106629
217
214
  requirements: []
218
215
  rubyforge_project: squeel
219
- rubygems_version: 1.8.10
216
+ rubygems_version: 1.3.9.4
220
217
  signing_key:
221
218
  specification_version: 3
222
219
  summary: ActiveRecord 3, improved.