# attr\_accessible question

**URL:** <https://discuss.rubyonrails.org/t/attr-accessible-question/63670>\
**Category:** rubyonrails-talk\
**Created:** [April 21, 2012, 6:39pm UTC](https://discuss.rubyonrails.org/t/attr-accessible-question/63670 "2012-04-21T18:39:31Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![11155](https://avatars.discourse-cdn.com/v4/letter/1/d26b3c/32.png) [@11155](https://discuss.rubyonrails.org/u/11155)\
**Post date:** [April 21, 2012, 6:39pm UTC](https://discuss.rubyonrails.org/t/attr-accessible-question/63670/1 "2012-04-21T18:39:31Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Frederick\_Cheung](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/frederick_cheung/32/3901_2.png) [@Frederick\_Cheung](https://discuss.rubyonrails.org/u/Frederick_Cheung)\
**Post date:** [April 23, 2012, 3:18am UTC](https://discuss.rubyonrails.org/t/attr-accessible-question/63670/2 "2012-04-23T03:18:26Z")

</div>

> 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| &nbsp;&nbsp;widget.colour\_id = params[:colour] &nbsp;&nbsp;.. 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
