Skip to content
This repository has been archived by the owner on Dec 12, 2018. It is now read-only.

Commit

Permalink
assignment protection now extends to nested attributes via hash/array…
Browse files Browse the repository at this point in the history
… nesting

example:
  @user.assign(params[:user], [:name, :role_id, {:friend_attributes => [:id, :name, :_destroy]}])
  • Loading branch information
cainlevy committed Aug 26, 2010
1 parent 0ad1130 commit 181b724
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/mass_assignment.rb
Expand Up @@ -31,7 +31,13 @@ def filter_attributes(attributes, options = {}) # could surely be refactored.
elsif options[:only] == :all
attributes
else
whitelist = options[:only].map(&:to_s)
whitelist = options[:only].map{|i| i.is_a?(Hash) ? i.keys.first.to_s : i.to_s}
options[:only].each do |i|
next unless i.is_a? Hash
name = i.keys.first.to_s
next unless attributes[name].is_a? Hash
attributes[name] = filter_attributes(attributes[name], :only => i.values.first)
end
attributes.reject { |k, v| !whitelist.include?(k.gsub(/\(.+/, "")) }
end
elsif options[:except]
Expand Down
14 changes: 14 additions & 0 deletions test/mass_assignment_test.rb
Expand Up @@ -10,6 +10,14 @@ def columns
]
end
end

def friend
@friend ||= User.new
end

def friend_attributes=(attributes)
friend.attributes = attributes
end
end

class ProtectedUser < User
Expand Down Expand Up @@ -65,6 +73,12 @@ def setup
assert_equal "Bob", @user.name
assert_nil @user.role_id
end

test "nested assignment" do
@user.assign(@attributes.merge(:friend_attributes => {:name => 'Joe', :role_id => 1}), [:name, :role_id, {:friend_attributes => [:name]}])
assert_equal "Joe", @user.friend.name
assert_nil @user.friend.role_id
end
end

class MassAssignmentPolicyTest < ActiveSupport::TestCase
Expand Down

0 comments on commit 181b724

Please sign in to comment.