mass_assignment 1.0.1 → 1.1.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/Rakefile +1 -1
- data/lib/mass_assignment.rb +21 -21
- data/test/mass_assignment_test.rb +13 -49
- data/test/models.rb +51 -0
- data/test/test_helper.rb +2 -1
- metadata +10 -8
data/Rakefile
CHANGED
data/lib/mass_assignment.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
module MassAssignment
|
2
2
|
def self.included(base)
|
3
|
-
base.class_eval do
|
3
|
+
base.class_eval do
|
4
|
+
class_attribute :assignment_policy, :instance_reader => false, :instance_writer => false
|
5
|
+
def self.mass_assignment_policy(val)
|
6
|
+
self.assignment_policy = val
|
7
|
+
end
|
8
|
+
end
|
4
9
|
end
|
5
10
|
|
6
11
|
# Basic Example:
|
@@ -24,27 +29,35 @@ module MassAssignment
|
|
24
29
|
# @user.save!
|
25
30
|
def assign(attributes, allowed_attributes = nil, &block)
|
26
31
|
return unless attributes and attributes.is_a? Hash
|
27
|
-
|
32
|
+
|
28
33
|
if allowed_attributes
|
29
34
|
safe_attributes = filter_attributes(attributes, :only => allowed_attributes)
|
30
35
|
yield attributes if block_given?
|
31
|
-
|
36
|
+
mass_assign_safe_attributes(safe_attributes)
|
32
37
|
else
|
33
|
-
if policy = self.class.
|
38
|
+
if policy = self.class.assignment_policy
|
34
39
|
safe_attributes = filter_attributes(attributes, policy)
|
35
|
-
|
40
|
+
mass_assign_safe_attributes(safe_attributes)
|
36
41
|
else
|
37
|
-
#
|
42
|
+
# fall back on Rails' system
|
38
43
|
self.attributes = attributes
|
39
44
|
end
|
40
45
|
end
|
41
46
|
end
|
42
|
-
|
47
|
+
|
43
48
|
private
|
44
49
|
|
50
|
+
def mass_assign_safe_attributes(safe_attributes)
|
51
|
+
if respond_to?(:assign_attributes)
|
52
|
+
assign_attributes(safe_attributes, :without_protection => true)
|
53
|
+
else
|
54
|
+
self.send("attributes=", safe_attributes, false)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
45
58
|
def filter_attributes(attributes, options = {}) # could surely be refactored.
|
46
59
|
attributes = attributes.stringify_keys
|
47
|
-
|
60
|
+
|
48
61
|
if options[:only]
|
49
62
|
if options[:only].is_a? Regexp
|
50
63
|
attributes.reject { |k, v| !k.gsub(/\(.+/, "").match(options[:only]) }
|
@@ -73,19 +86,6 @@ module MassAssignment
|
|
73
86
|
attributes
|
74
87
|
end
|
75
88
|
end
|
76
|
-
|
77
|
-
module ClassMethods
|
78
|
-
# sets a default mass assignment policy for your model's attributes. you may choose to start from a
|
79
|
-
# closed state that allows no mass assignment, an open state that allows any mass assignment (this is
|
80
|
-
# activerecord's default), or somewhere inbetween.
|
81
|
-
def mass_assignment_policy(val)
|
82
|
-
write_inheritable_attribute :mass_assignment_policy, val
|
83
|
-
end
|
84
|
-
|
85
|
-
def get_mass_assignment_policy
|
86
|
-
read_inheritable_attribute :mass_assignment_policy
|
87
|
-
end
|
88
|
-
end
|
89
89
|
end
|
90
90
|
|
91
91
|
ActiveRecord::Base.class_eval do include MassAssignment end
|
@@ -1,55 +1,19 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
|
-
class User < ActiveRecord::Base
|
4
|
-
class << self
|
5
|
-
def columns
|
6
|
-
@columns ||= [
|
7
|
-
ActiveRecord::ConnectionAdapters::Column.new("name", nil, "varchar(100)", true),
|
8
|
-
ActiveRecord::ConnectionAdapters::Column.new("email", nil, "varchar(100)", true),
|
9
|
-
ActiveRecord::ConnectionAdapters::Column.new("role_id", nil, "integer(11)", false)
|
10
|
-
]
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def friend
|
15
|
-
@friend ||= User.new
|
16
|
-
end
|
17
|
-
|
18
|
-
def friend_attributes=(attributes)
|
19
|
-
friend.attributes = attributes
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class ProtectedUser < User
|
24
|
-
attr_protected :role_id
|
25
|
-
end
|
26
|
-
|
27
|
-
class ClosedUser < User
|
28
|
-
mass_assignment_policy :except => :all
|
29
|
-
end
|
30
|
-
|
31
|
-
class SemiClosedUser < User
|
32
|
-
mass_assignment_policy :except => /_id$/
|
33
|
-
end
|
34
|
-
|
35
|
-
class OpenUser < User
|
36
|
-
mass_assignment_policy :only => :all
|
37
|
-
end
|
38
|
-
|
39
3
|
class MassAssignmentTest < ActiveSupport::TestCase
|
40
4
|
def setup
|
41
5
|
@user = ProtectedUser.new
|
42
6
|
@attributes = {"name" => "Bob", "email" => "bob@example.com"}
|
43
7
|
ActiveRecord::Base.logger = stub('debug' => true)
|
44
8
|
end
|
45
|
-
|
9
|
+
|
46
10
|
test "assigning nothing" do
|
47
11
|
params = {}
|
48
12
|
assert_nothing_raised do
|
49
13
|
@user.assign(params[:user])
|
50
14
|
end
|
51
15
|
end
|
52
|
-
|
16
|
+
|
53
17
|
test "assigning a string" do
|
54
18
|
params = {:user => "well this is embarrassing"}
|
55
19
|
assert_nothing_raised do
|
@@ -62,31 +26,31 @@ class MassAssignmentTest < ActiveSupport::TestCase
|
|
62
26
|
assert_equal "Bob", @user.name
|
63
27
|
assert_equal "bob@example.com", @user.email
|
64
28
|
end
|
65
|
-
|
29
|
+
|
66
30
|
test "assigning protected attributes" do
|
67
31
|
@user.assign(@attributes.merge(:role_id => 1))
|
68
32
|
assert_equal "Bob", @user.name
|
69
33
|
assert_nil @user.role_id
|
70
34
|
end
|
71
|
-
|
35
|
+
|
72
36
|
test "overriding protected attributes" do
|
73
37
|
@user.assign(@attributes.merge(:role_id => 1), [:name, :email, :role_id])
|
74
38
|
assert_equal "Bob", @user.name
|
75
39
|
assert_equal 1, @user.role_id
|
76
40
|
end
|
77
|
-
|
41
|
+
|
78
42
|
test "assigning unallowed attributes" do
|
79
43
|
@user.assign(@attributes.merge(:role_id => 1), [:name, :email])
|
80
44
|
assert_equal "Bob", @user.name
|
81
45
|
assert_nil @user.role_id
|
82
46
|
end
|
83
|
-
|
47
|
+
|
84
48
|
test "nested assignment" do
|
85
49
|
@user.assign(@attributes.merge(:friend_attributes => {:name => 'Joe', :role_id => 1}), [:name, :role_id, {:friend_attributes => [:name]}])
|
86
50
|
assert_equal "Joe", @user.friend.name
|
87
51
|
assert_nil @user.friend.role_id
|
88
52
|
end
|
89
|
-
|
53
|
+
|
90
54
|
test "deep assignment" do
|
91
55
|
@user.assign(@attributes.merge(:friend => {:name => 'Joe', :role_id => 1}), [:name, :role_id]) do |params|
|
92
56
|
@user.friend.assign(params[:friend], [:name])
|
@@ -101,42 +65,42 @@ class MassAssignmentPolicyTest < ActiveSupport::TestCase
|
|
101
65
|
@attributes = {"name" => "Bob", "role_id" => 1}
|
102
66
|
ActiveRecord::Base.logger = stub('debug' => true)
|
103
67
|
end
|
104
|
-
|
68
|
+
|
105
69
|
test "an open policy" do
|
106
70
|
@user = OpenUser.new
|
107
71
|
@user.assign(@attributes)
|
108
72
|
assert_equal "Bob", @user.name
|
109
73
|
assert_equal 1, @user.role_id
|
110
74
|
end
|
111
|
-
|
75
|
+
|
112
76
|
test "an overridden open policy" do
|
113
77
|
@user = OpenUser.new
|
114
78
|
@user.assign(@attributes, [:name])
|
115
79
|
assert_equal "Bob", @user.name
|
116
80
|
assert_nil @user.role_id
|
117
81
|
end
|
118
|
-
|
82
|
+
|
119
83
|
test "a closed policy" do
|
120
84
|
@user = ClosedUser.new
|
121
85
|
@user.assign(@attributes)
|
122
86
|
assert_nil @user.name
|
123
87
|
assert_nil @user.role_id
|
124
88
|
end
|
125
|
-
|
89
|
+
|
126
90
|
test "an overridden closed policy" do
|
127
91
|
@user = ClosedUser.new
|
128
92
|
@user.assign(@attributes, [:name, :role_id])
|
129
93
|
assert_equal "Bob", @user.name
|
130
94
|
assert_equal 1, @user.role_id
|
131
95
|
end
|
132
|
-
|
96
|
+
|
133
97
|
test "a semi-closed policy" do
|
134
98
|
@user = SemiClosedUser.new
|
135
99
|
@user.assign(@attributes)
|
136
100
|
assert_equal "Bob", @user.name
|
137
101
|
assert_nil @user.role_id
|
138
102
|
end
|
139
|
-
|
103
|
+
|
140
104
|
test "an overridden semi-closed policy" do
|
141
105
|
@user = SemiClosedUser.new
|
142
106
|
@user.assign(@attributes, [:name, :role_id])
|
data/test/models.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
class << self
|
3
|
+
def columns
|
4
|
+
@columns ||= [
|
5
|
+
ActiveRecord::ConnectionAdapters::Column.new("name", nil, "varchar(100)", true),
|
6
|
+
ActiveRecord::ConnectionAdapters::Column.new("email", nil, "varchar(100)", true),
|
7
|
+
ActiveRecord::ConnectionAdapters::Column.new("role_id", nil, "integer(11)", false)
|
8
|
+
]
|
9
|
+
end
|
10
|
+
|
11
|
+
def column_defaults
|
12
|
+
columns.inject({}) { |h, col| h.merge(col.name => col.default) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def columns_hash
|
16
|
+
columns.inject({}) { |h, col| h.merge(col.name => col) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def primary_key
|
20
|
+
'id'
|
21
|
+
end
|
22
|
+
|
23
|
+
def attributes_protected_by_default
|
24
|
+
[ primary_key ]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def friend
|
29
|
+
@friend ||= User.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def friend_attributes=(attributes)
|
33
|
+
friend.attributes = attributes
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class ProtectedUser < User
|
38
|
+
attr_protected :role_id
|
39
|
+
end
|
40
|
+
|
41
|
+
class ClosedUser < User
|
42
|
+
mass_assignment_policy :except => :all
|
43
|
+
end
|
44
|
+
|
45
|
+
class SemiClosedUser < User
|
46
|
+
mass_assignment_policy :except => /_id$/
|
47
|
+
end
|
48
|
+
|
49
|
+
class OpenUser < User
|
50
|
+
mass_assignment_policy :only => :all
|
51
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mass_assignment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Lance Ivy
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-11-21 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -45,8 +45,9 @@ files:
|
|
45
45
|
- LICENSE
|
46
46
|
- README.textile
|
47
47
|
- Rakefile
|
48
|
-
- test/test_helper.rb
|
49
48
|
- test/mass_assignment_test.rb
|
49
|
+
- test/models.rb
|
50
|
+
- test/test_helper.rb
|
50
51
|
has_rdoc: true
|
51
52
|
homepage: http://github.com/cainlevy/mass_assignment
|
52
53
|
licenses: []
|
@@ -77,10 +78,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
78
|
requirements: []
|
78
79
|
|
79
80
|
rubyforge_project:
|
80
|
-
rubygems_version: 1.
|
81
|
+
rubygems_version: 1.6.2
|
81
82
|
signing_key:
|
82
83
|
specification_version: 3
|
83
84
|
summary: Simple and secure params assignment for ActiveRecord
|
84
85
|
test_files:
|
85
|
-
- test/test_helper.rb
|
86
86
|
- test/mass_assignment_test.rb
|
87
|
+
- test/models.rb
|
88
|
+
- test/test_helper.rb
|