strong parameters permit all attributes for nested attributes

Solution 1:

The only situation I have encountered where permitting arbitrary keys in a nested params hash seems reasonable to me is when writing to a serialized column. I've managed to handle it like this:

class Post
  serialize :options, JSON
end

class PostsController < ApplicationController
  ...

  def post_params
    all_options = params.require(:post)[:options].try(:permit!)
    params.require(:post).permit(:title).merge(:options => all_options)
  end
end

try makes sure we do not require the presents of an :options key.

Solution 2:

Actually there is a way to just white-list all nested parameters.

params.require(:lever).permit(:name).tap do |whitelisted|
  whitelisted[:lever_benefit_attributes ] = params[:lever][:lever_benefit_attributes ]
end

This method has advantage over other solutions. It allows to permit deep-nested parameters.

While other solutions like:

nested_keys = params.require(:lever).fetch(:lever_benefit_attributes, {}).keys
params.require(:lever).permit(:name,:lever_benefit_attributes => nested_keys)

Don't.


Source:

https://github.com/rails/rails/issues/9454#issuecomment-14167664

Solution 3:

First, make sure that you really want to allow all values in a nested hash. Read through Damien MATHIEU's answer to understand the potential opening of security holes...

If you still need/want to allow all values in a hash (there are perfectly valid use cases for this, e.g. storing unstructured, user-provided metadata for a record), you can achieve it using the following bits of code:

def lever_params
  nested_keys = params.require(:lever).fetch(:lever_benefit_attributes, {}).keys
  params.require(:lever).permit(:name,:lever_benefit_attributes => nested_keys)
end

Note: This is very similar to tf.'s answer but a bit more elegant since you will not get any Unpermitted parameters: lever_benefit_attributes warnings/errors.

Solution 4:

I am surprised at no one suggested this:

params.require(:lever).permit(:name,:lever_benefit_attributes => {})