0

I want to access three keys from params.

Say my params is:

params = {
   'product_id' =>  11,
   'category' => {
                   'name' => 'Pet',
                   'sub_categories' => {5 => 'Name1', 7 => 'Name2'} ## **UPDATE**
                   'id' => 100
    },
    'user_action' => 'save'
}

Now I want to use strong parameters to filter these key out. i.e

#Inside controller
#action
def save_product_category
  product_params[:product_id]
  product_params[:category]
  product_params[:user_action]
end

private
  def product_params
     params.permit(:product_id, :user_action, :category) # Doesn't work, eliminates 'category' key
  end

How do I filter out these three keys?

UPDATE: I found one way to do it:

params.slice(:product_id, :category, :user_action)

Is it right way to do it?

UPDATE 2: Here is the correct answer:

params.permit(:product_id, :user_action, :category => [:id, :name, :sub_categories => {}])

Thanks @R_O_R and @twonegatives helping me out and bearing with me :)

Indyarocks
  • 643
  • 1
  • 6
  • 26

2 Answers2

1

Well you want

def product_params
  params.permit(:product_id, :user_action, category: [ :name, :id ])
end

Nested Parameters

Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • No they are not same. While using `slice` you are extracting your desired attributes from `params`, which is another `Hash` object, that you are using to update. But if you want to use directly the `param` object, you need to take the help of the **strong parameter**. – Arup Rakshit Jun 07 '15 at 18:06
  • Agreed. But in updated query, I've updated the parameter required inside 'category'. Can you please check `sub_categories` of `category` of `params` section of question above? – Indyarocks Jun 07 '15 at 18:08
  • @Indyarocks I checked that, and what I said is simply applied again. Just read the linked documentation, and you will get the idea. – Arup Rakshit Jun 07 '15 at 18:10
  • Yea, I went through the link. Thanks. The problem is: params.permit(:product_id, :user_action, :categories => [:id, :name, :sub_categories => [ ????]]), since the `keys` inside `sub_categories` hash are user input and not specific symbol/string key, how do I whitelist them? – Indyarocks Jun 07 '15 at 18:13
  • Got the answer. `params.permit(:product_id, :user_action, :categories => [:id, :name, :sub_categories => {}])` . Thanks. – Indyarocks Jun 07 '15 at 18:19
  • 1
    @Indyarocks glad you got answers.. :) – Arup Rakshit Jun 07 '15 at 18:21
1

You should explicitly define all the nested attributes of your parameters:

def product_params
  params.permit(:product_id, :user_action, category: [:id, :name] )
end

Reference to Rails 4 Strong parameters nested objects

UPDATE

As of your question about slice, well, that usage is possible aswell. Long story short, back in 2012 people used Rails 3 which did not provide any way of filtering incoming params in controller, so slice method was used for that purpose. Some references to that time can be even found here on stackoverflow (see slicing on mass assignment) and on github (here is a gist from DHH, creator of Ruby on Rails). At the end of the day, strong parameters gem is simply an extraction of the slice pattern. But for now it would be more convenient to follow permit pattern for Rails 4.

Community
  • 1
  • 1
twonegatives
  • 3,400
  • 19
  • 30
  • I've updated my answer with a note on `slice` method. – twonegatives Jun 07 '15 at 18:10
  • I've updated the parameter required inside 'category'. Can you please check sub_categories of category of params section of question above? Please refer comments of previous answer. – Indyarocks Jun 07 '15 at 18:18
  • @Indyarocks you should pay more attention to the links people route you to. this answer addresses exactly the last of your problems (could be found at Rails 4 strong params thread which I posted above): http://stackoverflow.com/a/24475600/1276552 – twonegatives Jun 07 '15 at 18:19
  • Got the answer. `params.permit(:product_id, :user_action, :categories => [:id, :name, :sub_categories => {}])` . Thanks. – Indyarocks Jun 07 '15 at 18:19
  • Thanks @twonegatives. In the link the answer had specific keys defined for `sub_categories`. `params.require(:foo).permit(:bar, {:baz => [:x, :y]})` `:x` and `:y`. I wanted to allow the complete hash. Anyways, apologies for not putting up my query clearly in first place. Thanks! – Indyarocks Jun 07 '15 at 18:22