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 +18 -18
- data/README.mdown +5 -7
- data/VERSION +1 -1
- data/lib/scoped_from/query.rb +15 -5
- data/spec/scoped_from/query_spec.rb +89 -27
- data/spec/spec_helper.rb +2 -2
- data/spec/support/bootsrap/database.rb +2 -1
- metadata +4 -4
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.
|
12
|
-
activemodel (= 3.1.
|
13
|
-
activesupport (= 3.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.
|
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.
|
22
|
-
activemodel (3.1.
|
23
|
-
activesupport (= 3.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.
|
27
|
-
activemodel (= 3.1.
|
28
|
-
activesupport (= 3.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.
|
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.
|
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.
|
40
|
+
json (1.6.2)
|
41
41
|
linecache (0.46)
|
42
42
|
rbx-require-relative (> 0.0.4)
|
43
|
-
multi_json (1.0.
|
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.
|
54
|
-
actionpack (= 3.1.
|
55
|
-
activesupport (= 3.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.
|
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
|
-
|
104
|
-
|
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, :
|
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.
|
1
|
+
0.3
|
data/lib/scoped_from/query.rb
CHANGED
@@ -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.
|
81
|
-
elsif @scope.scope_with_one_argument?(name)
|
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 =>
|
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 => [
|
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
|
171
|
-
query(User, { :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
|
175
|
-
query(User,
|
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 '
|
180
|
-
query(User, '
|
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 '
|
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 '
|
188
|
-
query(User,
|
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
|
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:
|
4
|
+
hash: 13
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
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-
|
17
|
+
date: 2011-11-30 00:00:00 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: activerecord
|