scoped_from 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -8,39 +8,39 @@ PATH
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- actionpack (3.1.1)
12
- activemodel (= 3.1.1)
13
- activesupport (= 3.1.1)
11
+ actionpack (3.1.3)
12
+ activemodel (= 3.1.3)
13
+ activesupport (= 3.1.3)
14
14
  builder (~> 3.0.0)
15
15
  erubis (~> 2.7.0)
16
16
  i18n (~> 0.6)
17
- rack (~> 1.3.2)
17
+ rack (~> 1.3.5)
18
18
  rack-cache (~> 1.1)
19
19
  rack-mount (~> 0.8.2)
20
20
  rack-test (~> 0.6.1)
21
- sprockets (~> 2.0.2)
22
- activemodel (3.1.1)
23
- activesupport (= 3.1.1)
21
+ sprockets (~> 2.0.3)
22
+ activemodel (3.1.3)
23
+ activesupport (= 3.1.3)
24
24
  builder (~> 3.0.0)
25
25
  i18n (~> 0.6)
26
- activerecord (3.1.1)
27
- activemodel (= 3.1.1)
28
- activesupport (= 3.1.1)
26
+ activerecord (3.1.3)
27
+ activemodel (= 3.1.3)
28
+ activesupport (= 3.1.3)
29
29
  arel (~> 2.2.1)
30
30
  tzinfo (~> 0.3.29)
31
- activesupport (3.1.1)
31
+ activesupport (3.1.3)
32
32
  multi_json (~> 1.0)
33
33
  arel (2.2.1)
34
34
  builder (3.0.0)
35
- columnize (0.3.4)
35
+ columnize (0.3.5)
36
36
  diff-lcs (1.1.3)
37
37
  erubis (2.7.0)
38
38
  hike (1.2.1)
39
39
  i18n (0.6.0)
40
- json (1.6.1)
40
+ json (1.6.2)
41
41
  linecache (0.46)
42
42
  rbx-require-relative (> 0.0.4)
43
- multi_json (1.0.3)
43
+ multi_json (1.0.4)
44
44
  rack (1.3.5)
45
45
  rack-cache (1.1)
46
46
  rack (>= 0.4)
@@ -50,9 +50,9 @@ GEM
50
50
  rack
51
51
  rack-test (0.6.1)
52
52
  rack (>= 1.0)
53
- railties (3.1.1)
54
- actionpack (= 3.1.1)
55
- activesupport (= 3.1.1)
53
+ railties (3.1.3)
54
+ actionpack (= 3.1.3)
55
+ activesupport (= 3.1.3)
56
56
  rack-ssl (~> 1.3.2)
57
57
  rake (>= 0.8.7)
58
58
  rdoc (~> 3.4)
@@ -88,7 +88,7 @@ GEM
88
88
  sqlite3 (>= 1.3.3)
89
89
  thor (0.14.6)
90
90
  tilt (1.3.3)
91
- tzinfo (0.3.30)
91
+ tzinfo (0.3.31)
92
92
 
93
93
  PLATFORMS
94
94
  ruby
data/README.mdown CHANGED
@@ -66,6 +66,8 @@ All scopes can be mapped with `scoped_from` method **except** scopes taking a
66
66
  Scopes with no argument are invoked if parameter value is evaluated as `true`.
67
67
  It includes `"true"`, `"yes"`, `"y"`, `"on"`, and `"1"` strings.
68
68
 
69
+ Columns are also automatically scoped.
70
+
69
71
  ## Scopes restriction
70
72
 
71
73
  You can restrict mapping to some scopes with `:only` option:
@@ -100,14 +102,10 @@ is equivalent to
100
102
 
101
103
  @posts = Post.search('bar').search('foo')
102
104
 
103
- By default, blank parameter values are ignored, you can include them with
104
- `:include_blank` option:
105
-
106
- @posts = Post.scoped_from(params, :include_blank => true)
107
-
108
- You may also want to filter on columns, just specify `:include_columns` option:
105
+ You may also not want to filter on columns, just specify `:exclude_columns`
106
+ option:
109
107
 
110
- @posts = Post.scoped_from(params, :include_columns => true)
108
+ @posts = Post.scoped_from(params, :exclude_columns => true)
111
109
 
112
110
  A query string can also be given to `scoped_from` method:
113
111
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2
1
+ 0.3
@@ -2,6 +2,7 @@ module ScopedFrom
2
2
 
3
3
  class Query
4
4
 
5
+ FALSE_VALUES = %w( false no n off 0 ).freeze
5
6
  ORDER_DIRECTIONS = %w( asc desc ).freeze
6
7
  TRUE_VALUES = %w( true yes y on 1 ).freeze
7
8
 
@@ -9,8 +10,6 @@ module ScopedFrom
9
10
 
10
11
  # Available options are: - :only : to restrict to specified keys.
11
12
  # - :except : to ignore specified keys.
12
- # - :include_blank : to include blank values
13
- # (default false).
14
13
  def initialize(scope, params, options = {})
15
14
  @scope = scope.scoped
16
15
  @options = options
@@ -46,6 +45,10 @@ module ScopedFrom
46
45
  scope
47
46
  end
48
47
 
48
+ def false?(value)
49
+ FALSE_VALUES.include?(value.to_s.strip.downcase)
50
+ end
51
+
49
52
  def order_to_sql(value)
50
53
  order = parse_order(value)
51
54
  "#{order[:column]} #{order[:direction].upcase}" if order.present?
@@ -71,16 +74,23 @@ module ScopedFrom
71
74
  @params = ActiveSupport::HashWithIndifferentAccess.new
72
75
  params.each do |name, value|
73
76
  values = [value].flatten
74
- values.delete_if(&:blank?) unless @options[:include_blank]
75
77
  next if values.empty?
76
78
  if name.to_s == 'order'
77
79
  order = parse_order(values.last)
78
80
  @params[name] = "#{order[:column]}.#{order[:direction]}" if order.present?
79
81
  elsif @scope.scope_without_argument?(name)
80
- @params[name] = true if values.any? { |value| true?(value) }
81
- elsif @scope.scope_with_one_argument?(name) || @options[:include_columns].present? && @scope.column_names.include?(name.to_s)
82
+ @params[name] = true if values.all? { |value| true?(value) }
83
+ elsif @scope.scope_with_one_argument?(name)
82
84
  value = values.many? ? values : values.first
83
85
  @params[name] = @params[name] ? [@params[name], value].flatten : value
86
+ elsif @options[:exclude_columns].blank? && @scope.column_names.include?(name.to_s)
87
+ if @scope.columns_hash[name.to_s].type == :boolean
88
+ @params[name] = true if values.all? { |value| true?(value) }
89
+ @params[name] = false if values.all? { |value| false?(value) }
90
+ else
91
+ value = values.many? ? values : values.first
92
+ @params[name] = @params[name] ? [@params[name], value].flatten : value
93
+ end
84
94
  end
85
95
  end
86
96
  @params.slice!(*[@options[:only]].flatten) if @options[:only].present?
@@ -6,6 +6,61 @@ describe ScopedFrom::Query do
6
6
  ScopedFrom::Query.new(scope, params, options)
7
7
  end
8
8
 
9
+ describe '#false?' do
10
+
11
+ it 'is true if false is given' do
12
+ query.send(:false?, false).should be_true
13
+ end
14
+
15
+ it 'is true if "false" is given' do
16
+ query.send(:false?, 'false').should be_true
17
+ query.send(:false?, 'False').should be_true
18
+ end
19
+
20
+ it 'is true if "0" is given' do
21
+ query.send(:false?, '0').should be_true
22
+ end
23
+
24
+ it 'is true if "off" is given' do
25
+ query.send(:false?, 'off').should be_true
26
+ query.send(:false?, 'OFF ').should be_true
27
+ end
28
+
29
+ it 'is true if "no" is given' do
30
+ query.send(:false?, 'no').should be_true
31
+ query.send(:false?, ' No ').should be_true
32
+ end
33
+
34
+ it 'is true if "n" is given' do
35
+ query.send(:false?, 'n').should be_true
36
+ query.send(:false?, 'N ').should be_true
37
+ end
38
+
39
+ it 'is false if true is given' do
40
+ query.send(:false?, true).should be_false
41
+ end
42
+
43
+ it 'is false if "true" is given' do
44
+ query.send(:false?, 'true').should be_false
45
+ query.send(:false?, 'TrUe').should be_false
46
+ end
47
+
48
+ it 'is false if "1" is given' do
49
+ query.send(:false?, '1').should be_false
50
+ end
51
+
52
+ it 'is false if "on" is given' do
53
+ query.send(:false?, "on").should be_false
54
+ query.send(:false?, "On").should be_false
55
+ end
56
+
57
+ it 'is false otherwise' do
58
+ query.send(:false?, 42).should be_false
59
+ query.send(:false?, 'bam').should be_false
60
+ end
61
+
62
+ end
63
+
9
64
  describe '#initialize' do
10
65
 
11
66
  it 'invokes #scoped method on specified scope' do
@@ -90,10 +145,6 @@ describe ScopedFrom::Query do
90
145
  query(User, :foo => 'bar', 'search' => 'foo', :enabled => true).params.should == { 'search' => 'foo', 'enabled' => true }
91
146
  end
92
147
 
93
- it 'removes blank values' do
94
- query(User, 'enabled' => true, 'search' => " \n").params.should == { 'enabled' => true }
95
- end
96
-
97
148
  it 'is case sensitive' do
98
149
  query(User, 'Enabled' => true, "SEARCH" => 'bar').params.should be_empty
99
150
  end
@@ -118,27 +169,32 @@ describe ScopedFrom::Query do
118
169
  query(User, 'search=bar&search=baz').params.should == { 'search' => ['bar', 'baz'] }
119
170
  end
120
171
 
121
- it 'removes blank values from array' do
122
- query(User, :search => [nil, 'bar', "\n ", 'baz']).params.should == { 'search' => ['bar', 'baz'] }
123
- end
124
-
125
172
  it 'converts value to true (or remove it) if scope takes no argument' do
126
173
  query(User, :latest => 'y').params.should == { 'latest' => true }
127
174
  query(User, :latest => 'no').params.should == {}
128
175
  end
129
176
 
177
+ it 'converts value to true (or false) if column is a boolean one' do
178
+ query(User, :admin => 'y').params.should == { 'admin' => true }
179
+ query(User, :admin => 'False').params.should == { 'admin' => false }
180
+ query(User, :admin => 'bar').params.should == {}
181
+ query(User, :admin => ['y', false]).params.should == {}
182
+ end
183
+
130
184
  it 'converts array value to true (or remove it) if scope takes no argument' do
131
- query(User, :latest => ['no', 'yes']).params.should == { 'latest' => true }
185
+ query(User, :latest => true).params.should == { 'latest' => true }
186
+ query(User, :latest => ['Yes']).params.should == { 'latest' => true }
187
+ query(User, :latest => ['no', 'yes']).params.should == {}
132
188
  query(User, :latest => ['no', nil]).params.should == {}
133
189
  query(User, :latest => ['fo']).params.should == {}
134
190
  end
135
191
 
136
192
  it 'flats array' do
137
- query(User, :search => [nil, ['bar', '', 'foo', ["\n ", 'baz']]]).params.should == { 'search' => ['bar', 'foo', 'baz'] }
193
+ query(User, :search => [nil, ['bar', '', 'foo', ["\n ", 'baz']]]).params.should == { 'search' => [nil, 'bar', '', 'foo', "\n ", 'baz'] }
138
194
  end
139
195
 
140
196
  it 'change array with a single value in one value' do
141
- query(User, :search => [nil, 'bar', "\n"]).params.should == { 'search' => 'bar' }
197
+ query(User, :search => ['bar']).params.should == { 'search' => 'bar' }
142
198
  end
143
199
 
144
200
  it 'does not modify given hash' do
@@ -156,40 +212,46 @@ describe ScopedFrom::Query do
156
212
  it 'accepts :only option' do
157
213
  query(User, { :search => 'bar', :enabled => 'true' }, :only => [:search]).params.should == { 'search' => 'bar' }
158
214
  query(User, { :search => 'bar', :enabled => 'true' }, :only => 'search').params.should == { 'search' => 'bar' }
215
+ query(User, { :search => 'bar', :firstname => 'Jane', :enabled => 'true' }, :only => 'search').params.should == { 'search' => 'bar' }
216
+ query(User, { :search => 'bar', :firstname => 'Jane', :enabled => 'true' }, :only => ['search', :firstname]).params.should == { 'search' => 'bar', 'firstname' => 'Jane' }
159
217
  end
160
218
 
161
219
  it 'accepts :except option' do
162
220
  query(User, { :search => 'bar', :enabled => true }, :except => [:search]).params.should == { 'enabled' => true }
163
221
  query(User, { :search => 'bar', :enabled => true }, :except => 'search').params.should == { 'enabled' => true }
222
+ query(User, { :search => 'bar', :firstname => 'Jane', :enabled => true }, :except => 'search').params.should == { 'enabled' => true, 'firstname' => 'Jane' }
223
+ query(User, { :search => 'bar', :firstname => 'Jane', :enabled => true }, :except => ['search', :firstname]).params.should == { 'enabled' => true }
164
224
  end
165
225
 
166
226
  it 'accepts a query instance' do
167
227
  query(User, query(User, :search => 'toto')).params.should == { 'search' => 'toto' }
168
228
  end
169
229
 
170
- it 'preserve blank values if :include_blank option is true' do
171
- query(User, { :search => "\n ", 'enabled' => true }, :include_blank => true).params.should == { 'search' => "\n ", 'enabled' => true }
230
+ it 'preserve blank values' do
231
+ query(User, { :search => "\n ", 'enabled' => true }).params.should == { 'search' => "\n ", 'enabled' => true }
232
+ end
233
+
234
+ it 'preserve blank values from array' do
235
+ query(User, { 'search' => ["\n ", 'toto', 'titi'] }).params.should == { 'search' => ["\n ", 'toto', 'titi'] }
236
+ query(User, { 'search' => [] }).params.should == {}
172
237
  end
173
238
 
174
- it 'preserve blank values from array if :include_blank option is true' do
175
- query(User, { 'search' => ["\n ", 'toto', 'titi'] }, :include_blank => true).params.should == { 'search' => ["\n ", 'toto', 'titi'] }
176
- query(User, { 'search' => [] }, :include_blank => true).params.should == {}
239
+ it 'also preserve blank on query string' do
240
+ query(User, 'search=%20&enabled=true&search=foo').params.should == { 'search' => [' ', 'foo'], 'enabled' => true }
177
241
  end
178
242
 
179
- it 'also preserve blank on query string if :include_blank option is true' do
180
- query(User, 'search=%20&enabled=true&search=foo', :include_blank => true).params.should == { 'search' => [' ', 'foo'], 'enabled' => true }
243
+ it 'includes column values' do
244
+ query(User, 'firstname' => 'Jane', 'foo' => 'bar').params.should == { 'firstname' => 'Jane' }
245
+ query(User, :firstname => 'Jane', 'foo' => 'bar').params.should == { 'firstname' => 'Jane' }
181
246
  end
182
247
 
183
- it 'removes column values' do
184
- query(User, 'firstname' => 'Jane', 'foo' => 'bar').params.should == {}
248
+ it 'exclude column values if :exclude_columns option is specified' do
249
+ query(User, { :enabled => true, 'firstname' => 'Jane', 'foo' => 'bar' }, :exclude_columns => true).params.should == { 'enabled' => true }
250
+ query(User, { :enabled => true, :firstname => 'Jane', :foo => 'bar' }, :exclude_columns => true).params.should == { 'enabled' => true }
185
251
  end
186
252
 
187
- it 'include column values if :include_columns option is specified' do
188
- query(User, { 'firstname' => 'Jane', 'foo' => 'bar' }, :include_columns => true).params.should == { 'firstname' => 'Jane' }
189
- query(User, { :firstname => 'Jane', :foo => 'bar' }, :include_columns => true).params.should == { 'firstname' => 'Jane' }
190
- query(User, { 'firstname' => ['Jane', 'John'], 'foo' => 'bar' }, :include_columns => true).params.should == { 'firstname' => ['Jane', 'John'] }
191
- query(User, { 'firstname' => "\n ", 'foo' => 'bar' }, :include_columns => true).params.should == {}
192
- query(User, { 'firstname' => "\n ", 'foo' => 'bar' }, :include_columns => true, :include_blank => true).params.should == { 'firstname' => "\n " }
253
+ it 'scopes have priority on columns' do
254
+ query(User, :enabled => false).params.should == {}
193
255
  end
194
256
 
195
257
  it 'maps an "order"' do
@@ -345,7 +407,7 @@ describe ScopedFrom::Query do
345
407
  query.send(:scoped, User, :created_between, true).should == User
346
408
  end
347
409
 
348
- it 'invokes scope without arguments if scope takes not argument' do
410
+ it 'invokes scope without arguments if scope takes no arguments' do
349
411
  query.send(:scoped, User.scoped, :enabled, true).should == [users(:john)]
350
412
  query.send(:scoped, User.scoped, :enabled, ' 1 ').should == [users(:john)]
351
413
  query.send(:scoped, User.scoped, :enabled, 'off').should == [users(:john)]
data/spec/spec_helper.rb CHANGED
@@ -19,7 +19,7 @@ RSpec.configure do |config|
19
19
  User.delete_all
20
20
  Vote.delete_all
21
21
 
22
- create_user(:john, :firstname => 'John', :lastname => 'Doe', :enabled => true)
23
- create_user(:jane, :firstname => 'Jane', :lastname => 'Doe', :enabled => false)
22
+ create_user(:john, :firstname => 'John', :lastname => 'Doe', :enabled => true, :admin => true)
23
+ create_user(:jane, :firstname => 'Jane', :lastname => 'Doe', :enabled => false, :admin => false)
24
24
  end
25
25
  end
@@ -5,7 +5,8 @@ ActiveRecord::Base.connection.create_table(:posts, :force => true)
5
5
  ActiveRecord::Base.connection.create_table(:users, :force => true) do |t|
6
6
  t.string :firstname, :null => false
7
7
  t.string :lastname, :null => false
8
- t.boolean :enabled, :null => false
8
+ t.boolean :enabled, :null => false, :default => false
9
+ t.boolean :admin, :null => false, :default => false
9
10
  t.timestamps
10
11
  end
11
12
  ActiveRecord::Base.connection.create_table(:votes, :force => true)
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scoped_from
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- version: "0.2"
8
+ - 3
9
+ version: "0.3"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Alexis Toulotte
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-10-27 00:00:00 Z
17
+ date: 2011-11-30 00:00:00 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: activerecord