Разрешение значений формы с сильными параметрами

Я пишу приложение викторины с rails 5. Пользователям предоставляются вопросы множественного выбора из базы данных. Для каждого вопроса пользователь может выбрать один параметр (переключатель) или несколько параметров (флажки). Это хранится в БД как логическое поле «multiselect».

Я использую form_for для построения формы.

<div class="answer-box">
      <% if m.object.multiselect %>
        <%= m.collection_check_boxes :answer, m.object.options, :id, :option_text, { checked: m.object.options.first.id } %>
      <% else %>
        <%= m.collection_radio_buttons :answer, m.object.options, :id, :option_text, { checked: m.object.options.first.id } %>
      <% end %>

      <%= m.hidden_field(:question_id, value: m.object.id) %>
      <%= m.hidden_field(:question_type, value: 'Mcq') %>
</div>

В контроллере я разрешил хэш params следующим образом :

def response_params
params.require(:quiz).permit(
  {
    mcq_responses_attributes: [
      :question_id,
      :question_type,
      answer: []
    ]
  })
end

Проблема заключается в том, когда вопрос является многозначным :ответ является массивом, а когда он является одинарным :ответ является целым числом. То, что я сделал, — это проверить, является ли :ответ массивом, а если нет, то преобразовать единственное целое число в массив, а затем разрешить его с помощью вышеуказанной функции.

def create_answer_array
  params[:quiz][:mcq_responses_attributes].each do |k, r|
    r[:answer] = Array(r[:answer]) unless r[:answer].is_a? Array
  end
end

Есть ли лучший способ сделать это?

1 ответ

  1. Это вообще хорошая практика, чтобы относиться к парам и все остальное из запроса как можно более неизменным.

    Вместо этого вы можете просто проверить свой метод санитарии params, какой из двух сценариев применим:

    def response_params
      p = params.require(:quiz)
      if params[:quiz][:answer].is_a? Array
        p.permit(:question_id, :question_type, answer: [])
      else
        p.permit(:question_id, :question_type, :answer)
      end
    end