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 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