Skip to content

Commit

Permalink
added scoped mass assignment support
Browse files Browse the repository at this point in the history
  • Loading branch information
GearHead90 committed Sep 5, 2011
1 parent 140f31f commit 2327c19
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 12 deletions.
30 changes: 25 additions & 5 deletions lib/mongoid/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,30 @@ def write_attribute(name, value)
end
alias :[]= :write_attribute


# Allows you to set all the attributes for a particular mass-assignment security role
# by passing in a hash of attributes with keys matching the attribute names
# (which again matches the column names) and the role name using the :as option.
# To bypass mass-assignment security you can use the :without_protection => true option.
#
# @example Assign the attributes.
# person.assign_attributes(:title => "Mr.")
#
# @example Assign the attributes (with a role).
# person.assign_attributes({ :title => "Mr." }, :as => :admin)
#
# @param [ Hash ] attrs The new attributes to set.
# @param [ Hash ] options Supported options: :without_protection, :as
#
# @since 2.2.1
def assign_attributes(attrs = nil, options = {})
assigning do
process(attrs, options[:as] || :default, !options[:without_protection]) do |document|
document.identify if new? && id.blank?
end
end
end

# Writes the supplied attributes hash to the document. This will only
# overwrite existing attributes if they are present in the new +Hash+, all
# others will be preserved.
Expand All @@ -122,11 +146,7 @@ def write_attribute(name, value)
#
# @since 1.0.0
def write_attributes(attrs = nil, guard_protected_attributes = true)
assigning do
process(attrs, guard_protected_attributes) do |document|
document.identify if new? && id.blank?
end
end
assign_attributes(attrs, :without_protection => !guard_protected_attributes)
end
alias :attributes= :write_attributes

Expand Down
9 changes: 6 additions & 3 deletions lib/mongoid/attributes/processing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ module Processing
# person.process(:title => "sir", :age => 40)
#
# @param [ Hash ] attrs The attributes to set.
# @param [ Symbol ] role A role for scoped mass assignment.
# @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
#
# @since 2.0.0.rc.7
def process(attrs = nil, guard_protected_attributes = true)
def process(attrs = nil, role = :default, guard_protected_attributes = true)
attrs ||= {}
attrs = sanitize_for_mass_assignment(attrs) if guard_protected_attributes
if guard_protected_attributes
attrs = (role == :default ? sanitize_for_mass_assignment(attrs) : sanitize_for_mass_assignment(attrs, role))
end
attrs.each_pair do |key, value|
next if pending_attribute?(key, value)
process_attribute(key, value)
Expand All @@ -37,7 +40,7 @@ def process(attrs = nil, guard_protected_attributes = true)
# @example Is the attribute pending?
# document.pending_attribute?(:name, "Durran")
#
# @param [ Synbol ] key The name of the attribute.
# @param [ Symbol ] key The name of the attribute.
# @param [ Object ] value The value of the attribute.
#
# @return [ true, false ] True if pending, false if not.
Expand Down
5 changes: 3 additions & 2 deletions lib/mongoid/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,14 @@ def identify
# Person.new(:title => "Sir")
#
# @param [ Hash ] attrs The attributes to set up the document with.
# @param [ Hash ] options A mass-assignment protection options. Supports :as and :without_protection
#
# @return [ Document ] A new document.
def initialize(attrs = nil)
def initialize(attrs = nil, options = {})
building do
@new_record = true
@attributes = apply_default_attributes
process(attrs) do
process(attrs, options[:as] || :default, !options[:without_protection]) do
yield self if block_given?
identify
end
Expand Down
5 changes: 3 additions & 2 deletions lib/mongoid/multi_parameter_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ def initialize(errors)
# person.process(:title => "sir", :age => 40)
#
# @param [ Hash ] attrs The attributes to set.
# @param [ Symbol ] role A role for scoped mass assignment.
# @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
#
# @since 2.0.0.rc.7
def process(attrs = nil, guard_protected_attributes = true)
def process(attrs = nil, role = :default, guard_protected_attributes = true)
if attrs
errors = []
attributes = {}
Expand Down Expand Up @@ -81,7 +82,7 @@ def process(attrs = nil, guard_protected_attributes = true)
)
end

super attributes, guard_protected_attributes
super attributes, role, guard_protected_attributes
else
super
end
Expand Down

0 comments on commit 2327c19

Please sign in to comment.