Home > Blockchain >  Rails strong parameters - multiple types (strings, array of strings and array of hashes)
Rails strong parameters - multiple types (strings, array of strings and array of hashes)

Time:01-16

I have the following params, that have different value type (1. string, 2. array of strings and 3. array of hashes) for the value key:

Params

project: {
  name: "Project 1",
  field_values_attributes: [
    {  
      field_component_id: 1, 
      value: "my_value"
    },
    {  
      field_component_id: 2, 
      value: ["my_value1", "my_value2"]
    },
    {  
      field_component_id: 3, 
      value: [
        {
          id: X,
          attributes: {
            uid: "my_uid",
            email: "my_email",
            full_name: "my_name"
          }
        }
      ]
    }
  ]
}

Strong params:

def project_params
  params.require(:project).permit(:name, field_values_attributes: [ :field_component_id, :value, value: [ :id, attributes: [:uid, :email, :full_name]] ])
end

The strong params method permits the string and array of hashes, but not array of strings for the value key.

Any idea how to write the permit method to accept all three types? Thanks.

CodePudding user response:

You can add value: [] for achieving this.

CodePudding user response:

You can have:

# for `value: "my_value"`
:value
 
# for `value: [{id: 1, ...}]`
value: [:id, attributes: [:uid, :email, :full_name]]

# for `value: ["my_value1", "my_value2"]`
value: []

But you can't have value: twice as a keyword argument for permit. You will have to do some manual shuffling:

project_params = params.require(:project).permit(:name).dup
project_params[:field_values_attributes] = params[:project][:field_values_attributes].map do |field|
  field.permit(
    :field_component_id,
    *case field[:value]
    in String
      [:value]
    in [String, *]
      [value: []]
    in [ActionController::Parameters, *]
      [value: [:id, attributes: [:uid, :email, :full_name]]]
    else
      []
    end
  )
end
project_params

#

>> project_params.permitted?
=> true
>> project_params.to_h 
=> {"name"=>"Project 1",
    "field_values_attributes"=>
     [{"field_component_id"=>1, "value"=>"my_value"},
      {"field_component_id"=>2, "value"=>["my_value1", "my_value2"]},
      {"field_component_id"=>3, "value"=>[{"id"=>4, "attributes"=>{"uid"=>"my_uid", "email"=>"my_email", "full_name"=>"my_name"}}]}]}
  • Related