hi, I was a little concerned with the rails de-facto update method (as used in rails''s scaffolds), because it simply calls <model>.update_attributes(params[:<model>]. This is very DRY indeed, but when some of the table''s fields contain valuable information that should be writable only by certain actions, you have to add some lines manually. Some code to demonstrate a potential weak scenario: # schematic view # form_tag :action => ''set_shop_styling'' text_field ''shop'', :header_color1 text_field ''shop'', :header_color2 submit_tag end_form tag # Controller # def set_shop_styling @shop.update_attributes(params[:shop]) end The set_shop_styling method may be accesssible to users who shouldn''t mess around with other attributes of the money-handling-chain in the example shop. I was a little bored of copy-pasting attribute filtering code, so I came up with an alternate version of ActiveRecord::Base.update_attributes # Updates all the attributes from the passed-in Hash and # saves the record. If the object is invalid, the saving # will fail and false will be returned. # # The options hash can be used to specify which attributes # are allowed for updating in this operation. This is useful # if the update_attributes call comes straight from # the controller''s +params[:something]+ , like in rails # scaffolds # # options: # allow:: an array of allowed attribute names as symbols def update_attributes(attributes, options={}) def_opts = {:allow => nil} options = def_opts.merge(options) attr = HashWithIndifferentAccess.new # Don''t check if not needed if options[:allow] != nil options[:allow].each { |p| attr[p] = attributes[p] if attributes.has_key? p print p } else attr = attributes end self.attributes = attr save end use it like update_attributes params[:shop], {:allow => [:header_color1, :header_color:2]} No big thing, but makes my life easier. If anyone''s interested, I can post some tests and later (if needed) a patch. If there''s a trivial (shorter :) ) way of doing this, please tell me... byz Gyula Laszlo profund d&s http://www.profund.hu
On Wed, May 24, 2006 at 03:30:56AM +0200, Laszlo Gyula wrote:> I was a little concerned with the rails de-facto update method (as used > in rails''s scaffolds), because it simply calls > <model>.update_attributes(params[:<model>]. This is very DRY indeed, but > when some of the table''s fields contain valuable information that should > be writable only by certain actions, you have to add some lines manually. > Some code to demonstrate a potential weak scenario:You can set attributes as protected from mass assignment with attr_protected. When an attribute is protected, only some_object.the_protected_attribute ''value'' will set it. When assigned using mass assignment, such as some_object.attributes = hash_of_attrs, it will simply be skipped. http://api.rubyonrails.com/classes/ActiveRecord/Base.html#M000873 marcel -- Marcel Molina Jr. <marcel@vernix.org>
Marcel Molina Jr. wrote:> On Wed, May 24, 2006 at 03:30:56AM +0200, Laszlo Gyula wrote: > >> I was a little concerned with the rails de-facto update method (as used >> in rails''s scaffolds), because it simply calls >> <model>.update_attributes(params[:<model>]. This is very DRY indeed, but >> when some of the table''s fields contain valuable information that should >> be writable only by certain actions, you have to add some lines manually. >> Some code to demonstrate a potential weak scenario: >> > > You can set attributes as protected from mass assignment with attr_protected. > When an attribute is protected, only some_object.the_protected_attribute > ''value'' will set it. When assigned using mass assignment, such as > some_object.attributes = hash_of_attrs, it will simply be skipped. > > http://api.rubyonrails.com/classes/ActiveRecord/Base.html#M000873 > > marcel >Actually, this isn''t what I was exactly looking for, mine is just a convinient form to clean up the controller, and to indicate (for ruby and equally for myself) exactly which attributes are to be updated, while attr_protected seals the whole model. Anyway, thanks for the help! Gyula Laszlo profund D&S http://profund.hu
On 25/05/2006, at 1:06 AM, Laszlo Gyula wrote:> Actually, this isn''t what I was exactly looking for, mine is just a > convinient form to clean up the controller, and > to indicate (for ruby and equally for myself) exactly which > attributes are to be updated, while attr_protected seals the > whole model.Or alternatively: %w(name email address).each { |f| @person[f] = params[:person][f] } -- tim lucas