0

I've built some in-line editing features using AJAX that allows a user to update lots of small bits of information on the page, and constructs JS to update the page afterwards. This same logic should handle tens of different mini-forms containing different attributes or sets of attributes (like firstname & lastname). In most cases, the value being changed is the same as the value to update on the page, so it's easy to write a Jquery call to update content accordingly. However sometimes I want to override what will be updated: for example, when a user changes their zipcode, their city and state should be displayed afterwards as well.

In these cases, I can add a form element to indicate what fields should be updated on the page. But the controller logic gets complicated when I consider security. I don't want a user to be able to change that form element to display any of their attributes; rather, I'd like to check whether a given attribute is in the whitelist of attributes they can update (strong parameters style), then use that information to decide whether the controller allows that attribute to be displayed on the page.

The strong parameters setup doesn't seem to allow for this. I can check whether a parameter is present in user_params, but if I'm not actually submitting a new value for that attribute via the params hash, it's treated as absent from user_params.

Is there any way to check whether an attribute is "on the whitelist", ie. would be accepted into user_params, even if we're not attempting to change it?

Or alternatively, is there another way you'd approach this need?

Topher Hunt
  • 4,404
  • 2
  • 27
  • 51

1 Answers1

1

I'd define the list of params that you're permitting in a constant and then check that. Here's a similar SO post that does this.

In short:

# In your model object (e.g. MyModel)
PERMITTED_FIELDS = %w(field1 field2 field3)

# In your controller
def my_object_params
  params.require(:user).permit(MyModel::PERMITTED_FIELDS)
end

Then you can access MyModel::PERMITTED_FIELDS as needed elsewhere.

Community
  • 1
  • 1
pdobb
  • 17,688
  • 5
  • 59
  • 74
  • Ah this will be perfect. I didn't know that #permit would accept an array. Thanks! – Topher Hunt May 28 '14 at 01:03
  • 1
    Glad to hear it. Note: even if #permit didn't accept an array, you could still start with one and then splat it with `*` (basically just removes the square brackets): `.permit(*MyModel::PERMITTED_FIELDS)`. – pdobb May 28 '14 at 01:06
  • Thanks again. I've seen the splat around but hadn't played with it much. This helps hugely! – Topher Hunt May 28 '14 at 01:08