How to permit hash with * key => values?

11k views Asked by At

I want to create an object with strong params that can accept dynamic hash keys.

This is my code,

Quiz.create(quiz_params)


def quiz_params
  params.require(:quiz).permit(:user_id, :percent, :grade, questions: {})
end

data that gets passed in would look something like this.

// the keys that get passed into question is always different

quiz: {
  user_id: 1,
  percent: 80,
  grade: "B",
  questions: {
    "12": "24",
    "1": "12",
    "4": "3",
    "5": "22"
  }
}

Currently however, when I try to create a Quiz, the questions hash turns out empty.

4

There are 4 answers

4
slowjack2k On BEST ANSWER

Until now I have only seen this:

def quiz_params
  questions_params = (params[:quiz] || {})[:questions].keys
  params.require(:quiz).permit(:user_id, :percent, :grade, questions: questions_params)
end
1
max On

Have you considered changing your api instead?

quiz: {
  user_id: 1,
  percent: 80,
  grade: "B",
  answers_attributes: [
    {
      question_id: "12"
      value: "24"
    }, 
    {
      question_id: "3"
      value: "12"
    }
    # ...
  ]
}

This is how both form_for and nested_attributes work. Instead of giving yourself a potential mass injection vulnerability - rethink your domain modeling. You can do better.

0
Derek On

In rails 5.1.2, the original syntax of passing an empty hash for questions should work:

def quiz_params
  params.require(:quiz).permit(:user_id, :percent, :grade, questions: {})
end

See https://github.com/rails/rails/commit/e86524c0c5a26ceec92895c830d1355ae47a7034

0
Jigar Bhatt On

Following way you can add new key/value in the strong parameter

class UserController < ApplicationController
  def create
    user_params[:department] = Department.find(params[:department_id]).name
    user = User.new(user_params)

    if user.save
      # success
    else
      # failure
    end
  end

  private

  def user_params
    @_user_params ||= params.require(:user).permit(:name, :department_id)
  end
end