I am using Restful_Authentication and stumbled upon their use of attr_accessible in the USER model. When I tried to migrate test USER records into my database and found that any non-attr_accessible field could not be updated. For those following my previous threads the message in the log was "Can't mass-assign these protected attributes: field1, field2, etc". (Thank you Mr. Cheung) I've read more about this ActiveRecord method see that it's wonderful for security reason, BUT how is the ADMIN supposed to update his critical fields that aren't included in the attr_accessible list? Thank you, Kathleen
either by assigning it directly to the object
@user.name = "Newname" @user.save
or with the singular form update_attribute
@user.update_attribute(:name, "Newname")
You can also tell activerecord to ignore the attr_protectedness of things: @user.send :attributes=, some_params, false
Fred
By using setter methods.
user.field1 = value
attr_protected/attr_accessible will ignore protected attributes mentioned in a MASS assignment, e.g.
user.attributes = {:field1 => value, ...}
or
User.create(:field1 => value,...)
but user.field1 = value will work.
I am familiar with editing a record using the form_for and passing the params hash to the update controller action. I must have not explained this clearly...how do we pass the 'protected' values to the fields that are non attr_accessible? Don't all values going from a view to a controller pass through a params hash? If we can't pass the values in the params hash, how do we get them to the update controller action? Thank you, Kathleen
You can’t ‘pass’ a value of a mass assignment protected attribute simply by passing the entire hash. Presumably the attribute is protected because you don’t want to allow any old value to be assigned because someone cooked up an ‘evil’ URL.
But you can extract the value from the params hash yourself, examine the value, and either reject or modify it.
def post @user = User.new(params[:user]). proposed_field1_value = params[:user][:field1]
@user.field1 = sanitize(proposed_field1_value) # Where sanitize is a controller method which removes any ‘evil’ from the value if @user.save #… else #… end end
or a refinement of this, which puts the code in the model where it belongs, is to add a method the model which takes the proposed value and sanitizes, ignores it or possibly raises an error. Maybe something like this ‘sketch’:
class User < ActiveRecord::Base #… def proposed_field1=(value) # check the value, scrub it if necessary, and if you want to set the value then… self.field1 = scrubbed_value end
end
Rick, Thank you for your kind description of passing a sensitive value inside a hash. I've got a boolean value in my USER model that basically unlocks the door for omnipotent privileges. As this is a boolean that only accepts 0 or 1, I cannot envision how this approach would work? Have you ever faced this challenge? Thank you, Kathleen