accessible_for 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +31 -27
- data/lib/accessible_for.rb +20 -4
- data/lib/mass_assignment_backport.rb +4 -18
- data/test/accessible_for_test.rb +22 -0
- data/test/mass_assignment_test.rb +12 -2
- metadata +1 -1
data/README.markdown
CHANGED
@@ -17,21 +17,20 @@ called accessible_for. They provide identical functionality.
|
|
17
17
|
|
18
18
|
# Usage
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
This is primarily intended for use in controller code. It should be possible
|
21
|
+
to use this with an ActiveRecord model as well, provided you use the
|
22
|
+
accessible_for API (to avoid name conflicts).
|
23
23
|
|
24
|
-
|
25
|
-
include MassAssignmentBackport
|
24
|
+
## accessible_for API
|
26
25
|
|
27
|
-
|
28
|
-
attr_accessible :rating
|
26
|
+
require 'accessible_for'
|
29
27
|
|
30
|
-
|
31
|
-
|
28
|
+
class TacoShop < Controller
|
29
|
+
include AccessibleFor
|
32
30
|
|
33
|
-
# and
|
34
|
-
|
31
|
+
# there are no implicit roles and you can declare only one group at a time
|
32
|
+
accessible_for :default => [ :filling, :topping, :rating ]
|
33
|
+
accessible_for :manager => [ :filling, :topping, :price ]
|
35
34
|
|
36
35
|
def update
|
37
36
|
Taco.find(params[:id]).update_attributes!(taco_params)
|
@@ -40,22 +39,31 @@ called accessible_for. They provide identical functionality.
|
|
40
39
|
protected
|
41
40
|
|
42
41
|
def taco_params
|
43
|
-
# use
|
44
|
-
#
|
45
|
-
|
42
|
+
# use sanitize_for(role, params) to build a safe hash
|
43
|
+
# again, there is no implicit role
|
44
|
+
if current_user.manager?
|
45
|
+
sanitize_for :manager, params[:taco]
|
46
|
+
else
|
47
|
+
sanitize_for :default, params[:taco]
|
48
|
+
end
|
46
49
|
end
|
47
50
|
end
|
48
51
|
|
49
|
-
##
|
52
|
+
## ActiveModel-workalike API
|
50
53
|
|
51
|
-
require '
|
54
|
+
require 'mass_assignment_backport'
|
52
55
|
|
53
56
|
class TacoShop < Controller
|
54
|
-
include
|
57
|
+
include MassAssignmentBackport
|
55
58
|
|
56
|
-
#
|
57
|
-
|
58
|
-
|
59
|
+
# when no role is specified, :default is used
|
60
|
+
attr_accessible :rating
|
61
|
+
|
62
|
+
# you can specify multiple roles
|
63
|
+
attr_accessible :filling, :topping, :as => [:default, :manager]
|
64
|
+
|
65
|
+
# and add to existing roles
|
66
|
+
attr_accessible :price, :as => :manager
|
59
67
|
|
60
68
|
def update
|
61
69
|
Taco.find(params[:id]).update_attributes!(taco_params)
|
@@ -64,13 +72,9 @@ called accessible_for. They provide identical functionality.
|
|
64
72
|
protected
|
65
73
|
|
66
74
|
def taco_params
|
67
|
-
# use
|
68
|
-
#
|
69
|
-
|
70
|
-
sanitize_for :manager, params[:taco]
|
71
|
-
else
|
72
|
-
sanitize_for :default, params[:taco]
|
73
|
-
end
|
75
|
+
# use sanitize_for_mass_assignment to build a safe hash given a role.
|
76
|
+
# when nothing/nil is passed for the role, :default is used
|
77
|
+
sanitize_for_mass_assignment params[:taco], current_user.manager? ? :manager : nil
|
74
78
|
end
|
75
79
|
end
|
76
80
|
|
data/lib/accessible_for.rb
CHANGED
@@ -1,23 +1,39 @@
|
|
1
1
|
require 'mass_assignment_backport'
|
2
2
|
|
3
3
|
module AccessibleFor
|
4
|
-
VERSION = "0.
|
4
|
+
VERSION = "0.3.0"
|
5
5
|
|
6
6
|
def self.included(mod)
|
7
|
-
mod.send :include, MassAssignmentBackport
|
8
7
|
mod.extend ClassMethods
|
9
8
|
end
|
10
9
|
|
11
10
|
module ClassMethods
|
11
|
+
attr_accessor :_accessible_attributes
|
12
|
+
|
12
13
|
def accessible_for params
|
13
14
|
params.each do |role, attrs|
|
14
|
-
|
15
|
+
self._accessible_attributes ||= {}
|
16
|
+
[role].flatten.each do |name|
|
17
|
+
self._accessible_attributes[name] ||= []
|
18
|
+
self._accessible_attributes[name] += [attrs].flatten
|
19
|
+
end
|
15
20
|
end
|
16
21
|
end
|
17
22
|
end
|
18
23
|
|
19
24
|
def sanitize_for role, values
|
20
|
-
|
25
|
+
return nil if values.nil?
|
26
|
+
if !self.class._accessible_attributes || self.class._accessible_attributes[role].nil?
|
27
|
+
return {}
|
28
|
+
end
|
29
|
+
{}.tap do |result|
|
30
|
+
values.each do |k, v|
|
31
|
+
if self.class._accessible_attributes[role].include?(k.to_sym)
|
32
|
+
yield k, v if block_given?
|
33
|
+
result[k] = v
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
21
37
|
end
|
22
38
|
end
|
23
39
|
|
@@ -1,18 +1,15 @@
|
|
1
1
|
module MassAssignmentBackport
|
2
2
|
def self.included(mod)
|
3
|
+
mod.send :include, AccessibleFor
|
3
4
|
mod.extend ClassMethods
|
4
5
|
end
|
5
6
|
|
6
7
|
module ClassMethods
|
7
|
-
attr_accessor :_accessible_attributes
|
8
8
|
|
9
9
|
def attr_accessible *args
|
10
10
|
options = args.last.kind_of?(Hash) ? args.pop : {}
|
11
11
|
role = options[:as] || :default
|
12
|
-
|
13
|
-
[role].flatten.each do |name|
|
14
|
-
self._accessible_attributes[name] = accessible_attributes(name) + args
|
15
|
-
end
|
12
|
+
accessible_for role => args
|
16
13
|
end
|
17
14
|
|
18
15
|
def accessible_attributes role=:default
|
@@ -20,19 +17,8 @@ module MassAssignmentBackport
|
|
20
17
|
end
|
21
18
|
end
|
22
19
|
|
23
|
-
def sanitize_for_mass_assignment values, role=:default
|
24
|
-
|
25
|
-
if !self.class._accessible_attributes || self.class._accessible_attributes[role].nil?
|
26
|
-
return values
|
27
|
-
end
|
28
|
-
{}.tap do |result|
|
29
|
-
values.each do |k, v|
|
30
|
-
if self.class._accessible_attributes[role].include?(k.to_sym)
|
31
|
-
yield k, v if block_given?
|
32
|
-
result[k] = v
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
20
|
+
def sanitize_for_mass_assignment values, role=:default, &block
|
21
|
+
sanitize_for role, values, &block
|
36
22
|
end
|
37
23
|
end
|
38
24
|
|
data/test/accessible_for_test.rb
CHANGED
@@ -5,6 +5,19 @@ class AccessibleForTest < MiniTest::Unit::TestCase
|
|
5
5
|
accessible_for :default => :topping
|
6
6
|
accessible_for :manager => [:price, :topping]
|
7
7
|
|
8
|
+
def test_nil_params
|
9
|
+
assert_nil sanitize_for(:default, nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_block_form
|
13
|
+
result = {}
|
14
|
+
sanitize_for(:default, :topping => 'salsa', :price => 123, :extra => 'foo') do |k,v|
|
15
|
+
result[k] = v
|
16
|
+
end
|
17
|
+
assert result.has_key?(:topping), "block gets accessible key"
|
18
|
+
assert !result.has_key?(:price), "block does not get inaccessible key"
|
19
|
+
end
|
20
|
+
|
8
21
|
def test_accessible_default
|
9
22
|
default = sanitize_for :default, :topping => 'salsa', :price => 123, :extra => 'foo'
|
10
23
|
assert default.has_key?(:topping), "default gets accessible key"
|
@@ -19,6 +32,15 @@ class AccessibleForTest < MiniTest::Unit::TestCase
|
|
19
32
|
assert !manager.has_key?(:extra), "role does not get extra key"
|
20
33
|
end
|
21
34
|
|
35
|
+
class UnspecifiedTest
|
36
|
+
include MassAssignmentBackport
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_unspecified_strips_values
|
40
|
+
unspec = UnspecifiedTest.new
|
41
|
+
assert_equal({}, unspec.sanitize_for(:default, :foo => :bar, :baz => :wubbo))
|
42
|
+
end
|
43
|
+
|
22
44
|
class SubTest
|
23
45
|
include AccessibleFor
|
24
46
|
accessible_for :default => :toasted
|
@@ -8,6 +8,16 @@ class MassAssignmentTest < MiniTest::Unit::TestCase
|
|
8
8
|
def test_nil_params
|
9
9
|
assert_nil sanitize_for_mass_assignment(nil)
|
10
10
|
end
|
11
|
+
|
12
|
+
def test_block_form
|
13
|
+
result = {}
|
14
|
+
sanitize_for_mass_assignment(:topping => 'salsa', :price => 123, :extra => 'foo') do |k,v|
|
15
|
+
result[k] = v
|
16
|
+
end
|
17
|
+
assert result.has_key?(:topping), "block gets accessible key"
|
18
|
+
assert !result.has_key?(:price), "block does not get inaccessible key"
|
19
|
+
end
|
20
|
+
|
11
21
|
def test_accessible_default
|
12
22
|
default = sanitize_for_mass_assignment :topping => 'salsa', :price => 123, :extra => 'foo'
|
13
23
|
assert default.has_key?(:topping), "default gets accessible key"
|
@@ -26,9 +36,9 @@ class MassAssignmentTest < MiniTest::Unit::TestCase
|
|
26
36
|
include MassAssignmentBackport
|
27
37
|
end
|
28
38
|
|
29
|
-
def
|
39
|
+
def test_unspecified_strips_values
|
30
40
|
unspec = UnspecifiedTest.new
|
31
|
-
assert_equal({
|
41
|
+
assert_equal({}, unspec.sanitize_for_mass_assignment(:foo => :bar, :baz => :wubbo))
|
32
42
|
end
|
33
43
|
|
34
44
|
class SubTest
|