mass_assignment 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
- require 'rake/rdoctask'
3
+ require 'rdoc/task'
4
4
 
5
5
  desc 'Default: run unit tests.'
6
6
  task :default => :test
@@ -1,6 +1,11 @@
1
1
  module MassAssignment
2
2
  def self.included(base)
3
- base.class_eval do extend ClassMethods end
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
- self.send("attributes=", safe_attributes, false)
36
+ mass_assign_safe_attributes(safe_attributes)
32
37
  else
33
- if policy = self.class.get_mass_assignment_policy
38
+ if policy = self.class.assignment_policy
34
39
  safe_attributes = filter_attributes(attributes, policy)
35
- self.send("attributes=", safe_attributes, false)
40
+ mass_assign_safe_attributes(safe_attributes)
36
41
  else
37
- # backwards compatibility. use attr_protected and attr_accessible.
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])
@@ -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
@@ -1,8 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
- gem 'rails', '3.0.7'
3
+ gem 'rails', '3.1.1'
4
4
  require 'active_support'
5
5
  require 'active_support/test_case'
6
6
  require 'active_record'
7
7
  require 'mass_assignment'
8
+ require 'models'
8
9
  require 'mocha'
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: 21
5
- prerelease: false
4
+ hash: 19
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
- - 0
9
8
  - 1
10
- version: 1.0.1
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-08-16 00:00:00 -04:00
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.3.7
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