8

How to permit/white-list deep-nested hashes with very un-regular (impossible to declare) structure.

Example:

{"widgets" => [
  {
    "id" => 75432,
    "conversion_goal_id" => 1331,
    "options" => {"form_settings"=>{"formbuilder-bg-color"=>"rgba(255, 255, 255, 0)", "font-size"=>"14px", "form-field-depth"=>"42px"}, "linkedWidget"=>""},
    "type" => "formbuilder-widget"
  },
  {
    "id" => 75433,
    "conversion_goal_id" => nil,
    "options" => {"width"=>"200px", "height"=>"185px", "display"=>"block", "left"=>313, "top"=>152, "position"=>"absolute"},
    "type" => "social-sharing-widget"
  },
  {},
]}

So options JSON/hash object doesn't have any specified structure.

It is formless.

It can be something like

{"width"=>"200px", "height"=>"185px", "display"=>"block", "left"=>313, "top"=>152, "position"=>"absolute"}

OR:

   {"form_settings"=>{"formbuilder-bg-color"=>"rgba(255, 255, 255, 0)", "font-size"=>"14px", "form-field-depth"=>"44px"},
    "linkedWidget"=>"",
    "required_height"=>164,
    "settings"=>
     [{"field_options"=>{"include_other_option"=>true, "size"=>"large", "view_label"=>false},
       "field_type"=>"text",
       "label"=>"Name:",
       "required"=>false,
       "asterisk"=>false,
       "textalign"=>"left"},
      {"field_options"=>{"include_other_option"=>true, "size"=>"large", "view_label"=>false},
       "field_type"=>"email",
       "label"=>"Email:",
       "required"=>false,
       "asterisk"=>false,
       "textalign"=>"left"},
      {"buttonalign"=>"left",
       "buttonbgcolor"=>"#ba7373",
       "buttonfont"=>"Old Standard TT",
       "buttonfontweight"=>"bold",
       "buttonfontstyle"=>"normal",
       "buttonfontsize"=>"18px",
       "buttonheight"=>"46px",
       "buttontxtcolor"=>"#ffffff",
       "field_options"=>{"include_other_option"=>true, "size"=>"large", "view_label"=>false},
       "field_type"=>"button",
       "label"=>"START LIVING",
       "required"=>true,
       "textalign"=>"left"}]}

Widgets node is just Array.

I didn't found any info how to whitelist nested attributes within array of hashes.

How to do this?

I found some info in documentation that I can specify keys directly,

page_params.permit({widgets: [:key1, :key2]})

But this won't work, since I want to permit ALL attributes/keys within options hash.

This solution, also doesn't support arrays, but it allows to white-list nested objects:

params.require(:screenshot).permit(:title).tap do |whitelisted|
  whitelisted[:assets_attributes ] = params[:screenshot][:assets_attributes ]
end

So how I can whitelist in every single element options attribute (array of hashes)?


REPLY TO COMMENTS:

  1. I need to allow everything within options attribute in widget node. Widget node is in widgets array. I still need to prevent other fields e.g. link_text, 'text_value' etc in array - I don't want them to be submitted.

  2. I need strong parameters to whitelist used parameters and backlist not used parameters. Some parameters exist only in front-end and don't exist in back-end. If I submit everything - then I will have exception.

Community
  • 1
  • 1
nothing-special-here
  • 11,230
  • 13
  • 64
  • 94
  • What are you doing with the `options` attribute? Strong params is generally used when doing mass assignment. – jvillian Feb 26 '16 at 23:24
  • `options` field is used for saving OPTIONS specific to given widget. Different widget have different options, so it is formless. – nothing-special-here Feb 29 '16 at 17:26
  • Can't believe almost 4 years after this question was posted, there still doesn't seem to be a way to accomplish this with an array of deeply nested dynamic hashes. – yuяi Aug 07 '19 at 23:28
  • Couldn't you just JSONify the options value on the frontend before sending and then `JSON.parse` on the backend? – Scott Schupbach Jan 02 '20 at 23:06

1 Answers1

-4

Maybe I don't follow what you're trying to do here. Strong params are to prevent a user from submitting malicious data, so it basically whitelists certain keys. If you want to allow for everything, what do you need strong params for?

vikram7
  • 495
  • 3
  • 12
  • I need to allow everything within `options` attribute in widget node. Widget node is in `widgets` array. I still need to prevent other fields e.g. `spam2` in array - I don't want them to be submitted. – nothing-special-here Feb 26 '16 at 19:18
  • I need strong parameters to whitelist used parameters and backlist not used parameters. Some parameters exist only in front-end and don't exist in back-end. If I submit everything - then I will have exception. – nothing-special-here Feb 26 '16 at 19:19
  • 3
    This should be a comment, not an answer. – Cary Swoveland Feb 26 '16 at 20:02