scoped_from 0.2 → 0.3

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/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