has_scope 0.4.2 → 0.5.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.rdoc +6 -0
- data/Rakefile +1 -1
- data/lib/has_scope.rb +34 -18
- data/test/has_scope_test.rb +12 -2
- data/test/test_helper.rb +11 -4
- metadata +12 -5
data/README.rdoc
CHANGED
@@ -20,6 +20,7 @@ Now, if you want to apply them to an specific resource, you just need to call <t
|
|
20
20
|
class GraduationsController < ApplicationController
|
21
21
|
has_scope :featured, :type => :boolean
|
22
22
|
has_scope :by_degree
|
23
|
+
has_scope :by_period, :using => [:started_at, :ended_at]
|
23
24
|
|
24
25
|
def index
|
25
26
|
@graduations = apply_scopes(Graduation).all
|
@@ -37,6 +38,9 @@ Then for each request:
|
|
37
38
|
/graduations?featured=true&by_degree=phd
|
38
39
|
#=> brings featured graduations with phd degree
|
39
40
|
|
41
|
+
/graduations?params[by_period][started_at]=20100701¶ms[by_period][ended_at]=20101013
|
42
|
+
#=> brings graduations in the given period
|
43
|
+
|
40
44
|
You can retrieve all the scopes applied in one action with <tt>current_scopes</tt> method.
|
41
45
|
In the last case, it would return: { :featured => true, :by_degree => "phd" }.
|
42
46
|
|
@@ -62,6 +66,8 @@ HasScope supports several options:
|
|
62
66
|
|
63
67
|
* <tt>:as</tt> - The key in the params hash expected to find the scope. Defaults to the scope name.
|
64
68
|
|
69
|
+
* <tt>:using</tt> - The subkeys to be used as args when type is a hash.
|
70
|
+
|
65
71
|
* <tt>:if</tt> - Specifies a method, proc or string to call to determine if the scope should apply.
|
66
72
|
|
67
73
|
* <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the scope should NOT apply.
|
data/Rakefile
CHANGED
@@ -27,7 +27,7 @@ begin
|
|
27
27
|
require 'jeweler'
|
28
28
|
Jeweler::Tasks.new do |s|
|
29
29
|
s.name = "has_scope"
|
30
|
-
s.version = "0.
|
30
|
+
s.version = "0.5.0"
|
31
31
|
s.summary = "Maps controller filters to your resource scopes"
|
32
32
|
s.email = "contact@plataformatec.com.br"
|
33
33
|
s.homepage = "http://github.com/plataformatec/has_scope"
|
data/lib/has_scope.rb
CHANGED
@@ -33,6 +33,9 @@ module HasScope
|
|
33
33
|
# * <tt>:as</tt> - The key in the params hash expected to find the scope.
|
34
34
|
# Defaults to the scope name.
|
35
35
|
#
|
36
|
+
# * <tt>:using</tt> - If type is a hash, you can provide :using to convert the hash to
|
37
|
+
# a named scope call with several arguments.
|
38
|
+
#
|
36
39
|
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
|
37
40
|
# if the scope should apply
|
38
41
|
#
|
@@ -61,7 +64,17 @@ module HasScope
|
|
61
64
|
def has_scope(*scopes, &block)
|
62
65
|
options = scopes.extract_options!
|
63
66
|
options.symbolize_keys!
|
64
|
-
options.assert_valid_keys(:type, :only, :except, :if, :unless, :default, :as, :allow_blank)
|
67
|
+
options.assert_valid_keys(:type, :only, :except, :if, :unless, :default, :as, :using, :allow_blank)
|
68
|
+
|
69
|
+
if options.key?(:using)
|
70
|
+
if options.key?(:type) && options[:type] != :hash
|
71
|
+
raise "You cannot use :using with another :type different than :hash"
|
72
|
+
else
|
73
|
+
options[:type] = :hash
|
74
|
+
end
|
75
|
+
|
76
|
+
options[:using] = Array(options[:using])
|
77
|
+
end
|
65
78
|
|
66
79
|
options[:only] = Array(options[:only])
|
67
80
|
options[:except] = Array(options[:except])
|
@@ -80,7 +93,7 @@ module HasScope
|
|
80
93
|
# Receives an object where scopes will be applied to.
|
81
94
|
#
|
82
95
|
# class GraduationsController < InheritedResources::Base
|
83
|
-
# has_scope :featured, :
|
96
|
+
# has_scope :featured, :type => true, :only => :index
|
84
97
|
# has_scope :by_degree, :only => :index
|
85
98
|
#
|
86
99
|
# def index
|
@@ -88,23 +101,25 @@ module HasScope
|
|
88
101
|
# end
|
89
102
|
# end
|
90
103
|
#
|
91
|
-
def apply_scopes(target)
|
104
|
+
def apply_scopes(target, hash=params)
|
92
105
|
return target unless scopes_configuration
|
93
106
|
|
94
107
|
self.scopes_configuration.each do |scope, options|
|
95
108
|
next unless apply_scope_to_action?(options)
|
96
109
|
key = options[:as]
|
97
110
|
|
98
|
-
if
|
99
|
-
value, call_scope =
|
111
|
+
if hash.key?(key)
|
112
|
+
value, call_scope = hash[key], true
|
100
113
|
elsif options.key?(:default)
|
101
114
|
value, call_scope = options[:default], true
|
102
115
|
value = value.call(self) if value.is_a?(Proc)
|
103
116
|
end
|
104
117
|
|
118
|
+
value = parse_value(options[:type], key, value)
|
119
|
+
|
105
120
|
if call_scope && (value.present? || options[:allow_blank])
|
106
|
-
|
107
|
-
target =
|
121
|
+
current_scopes[key] = value
|
122
|
+
target = call_scope_by_type(options[:type], scope, target, value, options)
|
108
123
|
end
|
109
124
|
end
|
110
125
|
|
@@ -112,24 +127,25 @@ module HasScope
|
|
112
127
|
end
|
113
128
|
|
114
129
|
# Set the real value for the current scope if type check.
|
115
|
-
def
|
130
|
+
def parse_value(type, key, value) #:nodoc:
|
116
131
|
if type == :boolean
|
117
|
-
|
118
|
-
elsif ALLOWED_TYPES[type].none?{ |klass| value.is_a?(klass) }
|
132
|
+
TRUE_VALUES.include?(value)
|
133
|
+
elsif value && ALLOWED_TYPES[type].none?{ |klass| value.is_a?(klass) }
|
119
134
|
raise "Expected type :#{type} in params[:#{key}], got #{value.class}"
|
120
135
|
else
|
121
|
-
|
136
|
+
value
|
122
137
|
end
|
123
138
|
end
|
124
139
|
|
125
|
-
#
|
126
|
-
def
|
140
|
+
# Call the scope taking into account its type.
|
141
|
+
def call_scope_by_type(type, scope, target, value, options) #:nodoc:
|
142
|
+
block = options[:block]
|
143
|
+
|
127
144
|
if type == :boolean
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
end
|
145
|
+
block ? block.call(self, target) : target.send(scope)
|
146
|
+
elsif value && options.key?(:using)
|
147
|
+
value = value.values_at(*options[:using])
|
148
|
+
block ? block.call(self, target, value) : target.send(scope, *value)
|
133
149
|
else
|
134
150
|
block ? block.call(self, target, value) : target.send(scope, value)
|
135
151
|
end
|
data/test/has_scope_test.rb
CHANGED
@@ -10,6 +10,7 @@ class TreesController < ApplicationController
|
|
10
10
|
has_scope :root_type, :as => :root, :allow_blank => true
|
11
11
|
has_scope :calculate_height, :default => proc {|c| c.session[:height] || 20 }, :only => :new
|
12
12
|
has_scope :paginate, :type => :hash
|
13
|
+
has_scope :args_paginate, :type => :hash, :using => [:page, :per_page]
|
13
14
|
has_scope :categories, :type => :array
|
14
15
|
|
15
16
|
has_scope :only_short, :type => :boolean do |controller, scope|
|
@@ -63,7 +64,7 @@ class HasScopeTest < ActionController::TestCase
|
|
63
64
|
Tree.expects(:all).returns([mock_tree])
|
64
65
|
get :index, :only_tall => 'false'
|
65
66
|
assert_equal([mock_tree], assigns(:trees))
|
66
|
-
assert_equal({
|
67
|
+
assert_equal({}, current_scopes)
|
67
68
|
end
|
68
69
|
|
69
70
|
def test_scope_is_called_only_on_index
|
@@ -134,7 +135,7 @@ class HasScopeTest < ActionController::TestCase
|
|
134
135
|
end
|
135
136
|
|
136
137
|
def test_scope_of_type_hash
|
137
|
-
hash = { "page" => "1", "per_page" => "
|
138
|
+
hash = { "page" => "1", "per_page" => "10" }
|
138
139
|
Tree.expects(:paginate).with(hash).returns(Tree)
|
139
140
|
Tree.expects(:all).returns([mock_tree])
|
140
141
|
get :index, :paginate => hash
|
@@ -142,6 +143,15 @@ class HasScopeTest < ActionController::TestCase
|
|
142
143
|
assert_equal({ :paginate => hash }, current_scopes)
|
143
144
|
end
|
144
145
|
|
146
|
+
def test_scope_of_type_hash_with_using
|
147
|
+
hash = { "page" => "1", "per_page" => "10" }
|
148
|
+
Tree.expects(:args_paginate).with("1", "10").returns(Tree)
|
149
|
+
Tree.expects(:all).returns([mock_tree])
|
150
|
+
get :index, :args_paginate => hash
|
151
|
+
assert_equal([mock_tree], assigns(:trees))
|
152
|
+
assert_equal({ :args_paginate => hash }, current_scopes)
|
153
|
+
end
|
154
|
+
|
145
155
|
def test_scope_of_type_array
|
146
156
|
array = %w(book kitchen sport)
|
147
157
|
Tree.expects(:categories).with(array).returns(Tree)
|
data/test/test_helper.rb
CHANGED
@@ -19,14 +19,21 @@ RAILS_ROOT = "anywhere"
|
|
19
19
|
|
20
20
|
require 'active_support'
|
21
21
|
require 'action_controller'
|
22
|
-
require '
|
23
|
-
require 'action_controller/test_process'
|
22
|
+
require 'action_dispatch/middleware/flash'
|
24
23
|
|
25
24
|
class ApplicationController < ActionController::Base; end
|
26
25
|
|
27
26
|
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
28
27
|
require 'has_scope'
|
29
28
|
|
30
|
-
|
29
|
+
HasScope::Router = ActionDispatch::Routing::RouteSet.new
|
30
|
+
HasScope::Router.draw do |map|
|
31
31
|
map.connect ':controller/:action/:id'
|
32
|
-
|
32
|
+
map.connect ':controller/:action'
|
33
|
+
end
|
34
|
+
|
35
|
+
class ActiveSupport::TestCase
|
36
|
+
setup do
|
37
|
+
@router = HasScope::Router
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_scope
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 5
|
8
|
+
- 0
|
9
|
+
version: 0.5.0
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- "Jos\xC3\xA9 Valim"
|
@@ -9,7 +14,7 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-03-23 00:00:00 +01:00
|
13
18
|
default_executable:
|
14
19
|
dependencies: []
|
15
20
|
|
@@ -40,18 +45,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
45
|
requirements:
|
41
46
|
- - ">="
|
42
47
|
- !ruby/object:Gem::Version
|
48
|
+
segments:
|
49
|
+
- 0
|
43
50
|
version: "0"
|
44
|
-
version:
|
45
51
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
52
|
requirements:
|
47
53
|
- - ">="
|
48
54
|
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
49
57
|
version: "0"
|
50
|
-
version:
|
51
58
|
requirements: []
|
52
59
|
|
53
60
|
rubyforge_project:
|
54
|
-
rubygems_version: 1.3.
|
61
|
+
rubygems_version: 1.3.6
|
55
62
|
signing_key:
|
56
63
|
specification_version: 3
|
57
64
|
summary: Maps controller filters to your resource scopes
|