Hi! I''m new to Rails and to this forum, so let me know if I''m posting incorrectly. I''m trying to understand accessible attributes (attr_accessible). I''m working with Ruby 1.9.3, and Rails 3.2.3. Here''s my scenario: I have four tables: colors, shapes, customers, and widgets. Colors table has id and color. Shapes table has id and shape. Customers table has id and customer. Widgets table has id, color_id, shape_id, and customer_id. The relationships are as you might expect: colors, shapes, and customers all have many widgets, and widgets belongs to colors, shapes, and customers. To create a new widget in the widgets controller, I scope it through a customer, roughly like this (syntax may have errors, but you get the idea): current_customer.widgets.create(color_id: params[:color], shape_id: params[:shape]) (as you can probably guess, current_customer is the current logged-in user) Okay, so given that basic scenario, on to my questions. My main question is whether I must keep the color_id and shape_id attributes accessible via mass assignment in the widgets controller. Or, is there a way to keep them inaccessible via mass assignment and still make this work. In other words, in Rails 3.2.3, do I need this line in my app/models/widgets.rb file: attr_accessible :color_id, :shape_id So far I''ve tried leaving this out, but my rspec threw a mass assignment security error because of this line in my spec: before { @widget = customer.widgets.build(color_id: color.id, shape_id: shape.id) } If I leave these attributes accessible, am I leaving a security hole (where a user can alter a color_id or shape_id of an existing record without authorization)? Or is it sufficient that I''ve scoped the creation of a widget through a current_user? Thanks, Brian -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Apr 22, 2:39 am, "Brian H." <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> > Okay, so given that basic scenario, on to my questions. > > My main question is whether I must keep the color_id and shape_id > attributes accessible via mass assignment in the widgets controller. Or, > is there a way to keep them inaccessible via mass assignment and still > make this work.If you want to be able to pass hashes with color/shape_id to build/ create/update_attributes then yes, you need those attr_accessible statements. Regardless of what attr_accessible stuff you have, you can always do some_widget.color_id = params[:color] as of the current versions, build and create should take blocks so you could do curent_customer.widgets.create do |widget| widget.colour_id = params[:colour] .. end> > In other words, in Rails 3.2.3, do I need this line in my > app/models/widgets.rb file: > attr_accessible :color_id, :shape_id > > So far I''ve tried leaving this out, but my rspec threw a mass assignment > security error because of this line in my spec: > before { @widget = customer.widgets.build(color_id: color.id, shape_id: > shape.id) }That is one of the annoyances of the attr_accessible stuff (the rails core team are currently trialling a more controller based approach - there was a post on the rails blog not that long ago) - in specs you''ll very often want to set arbitrary attributes. If you don''t mark the attributes as accessible, one way is before{ @widget = customer.widgets.build({color_id: color.id, shape_id: shape.id}, without_protection: true) } although I find the extra verboseness a bit annoying too.> > If I leave these attributes accessible, am I leaving a security hole > (where a user can alter a color_id or shape_id of an existing record > without authorization)? Or is it sufficient that I''ve scoped the > creation of a widget through a current_user?It largely depends on where/how you call build/create/ update_attributes. if you only ever called them on a scoped collection or on a widget that you have already verified belongs to the customer and if it is OK for a user to set color_id/shape_id to an arbitrary value then there''s no downside to making them attr_accessible. Or to look at it another way, look at everywhere you call build/create/ update_attributes and ask yourself if you''re ok with those calls setting color_id/shape_id to an arbitrary value chosen by the user. Fred -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.