module MongoModel module AttributeMethods module Protected extend ActiveSupport::Concern module ClassMethods def property(name, *args, &block)#:nodoc: property = super(name, *args, &block) attr_protected(name) if property.options[:protected] attr_accessible(name) if property.options[:accessible] property end # Attributes named in this macro are protected from mass-assignment, # such as new(attributes), # update_attributes(attributes), or # attributes=(attributes). # # Mass-assignment to these attributes will simply be ignored, to assign # to them you can use direct writer methods. This is meant to protect # sensitive attributes from being overwritten by malicious users # tampering with URLs or forms. # # class Customer < Recliner::Document # attr_protected :credit_rating # end # # customer = Customer.new("name" => David, "credit_rating" => "Excellent") # customer.credit_rating # => nil # customer.attributes = { "description" => "Jolly fellow", "credit_rating" => "Superb" } # customer.credit_rating # => nil # # customer.credit_rating = "Average" # customer.credit_rating # => "Average" # # To start from an all-closed default and enable attributes as needed, # have a look at +attr_accessible+. # # If the access logic of your application is richer you can use Hash#except # or Hash#slice to sanitize the hash of parameters before they are # passed to Recliner. # # For example, it could be the case that the list of protected attributes # for a given model depends on the role of the user: # # # Assumes plan_id is not protected because it depends on the role. # params[:account] = params[:account].except(:plan_id) unless admin? # @account.update_attributes(params[:account]) # # Note that +attr_protected+ is still applied to the received hash. Thus, # with this technique you can at most _extend_ the list of protected # attributes for a particular mass-assignment call. def attr_protected(*attrs) write_inheritable_attribute(:attr_protected, attrs.map { |a| a.to_s } + protected_attributes) end # Specifies a white list of model attributes that can be set via # mass-assignment, such as new(attributes), # update_attributes(attributes), or # attributes=(attributes) # # This is the opposite of the +attr_protected+ macro: Mass-assignment # will only set attributes in this list, to assign to the rest of # attributes you can use direct writer methods. This is meant to protect # sensitive attributes from being overwritten by malicious users # tampering with URLs or forms. If you'd rather start from an all-open # default and restrict attributes as needed, have a look at # +attr_protected+. # # class Customer < Recliner::Document # attr_accessible :name, :nickname # end # # customer = Customer.new(:name => "David", :nickname => "Dave", :credit_rating => "Excellent") # customer.credit_rating # => nil # customer.attributes = { :name => "Jolly fellow", :credit_rating => "Superb" } # customer.credit_rating # => nil # # customer.credit_rating = "Average" # customer.credit_rating # => "Average" # # If the access logic of your application is richer you can use Hash#except # or Hash#slice to sanitize the hash of parameters before they are # passed to Recliner. # # For example, it could be the case that the list of accessible attributes # for a given model depends on the role of the user: # # # Assumes plan_id is accessible because it depends on the role. # params[:account] = params[:account].except(:plan_id) unless admin? # @account.update_attributes(params[:account]) # # Note that +attr_accessible+ is still applied to the received hash. Thus, # with this technique you can at most _narrow_ the list of accessible # attributes for a particular mass-assignment call. def attr_accessible(*attrs) write_inheritable_attribute(:attr_accessible, attrs.map { |a| a.to_s } + accessible_attributes) end # Returns an array of all the attributes that have been protected from mass-assignment. def protected_attributes read_inheritable_attribute(:attr_protected) || [] end # Returns an array of all the attributes that have been made accessible to mass-assignment. def accessible_attributes read_inheritable_attribute(:attr_accessible) || [] end end def attributes=(attrs)#:nodoc: super(remove_protected_attributes(attrs)) end private def remove_protected_attributes(attrs) if self.class.accessible_attributes.empty? attrs.reject { |k, v| self.class.protected_attributes.include?(k.to_s) } else attrs.reject { |k, v| !self.class.accessible_attributes.include?(k.to_s) } end end end end end