Использование строгих параметров с вложенным параметром JSON - PullRequest
0 голосов
/ 24 января 2020

У меня есть форма обновления в моем веб-приложении, и у меня возникают проблемы при разрешении параметров, которые я получаю из этой формы. Вот как параметры попадают в контроллер:

<ActionController::Parameters {"company"=>{"description"=>"description", 
"email_address"=>"contact@gmail.com", 
"hours"=>"{\"fri\":[],\"mon\":[[\"09:00\",\"16:00\"]],\"sat\":[],
\"sun\":[[\"09:00\",\"16:00\"]],
\"thu\":[[\"09:00\",\"12:00\"], [\"13:00\",\"16:00\"]],
\"tue\":[[\"08:45\",\"16:00\"]],\"wed\":[[\"09:00\",\"16:00\"]]}"}, 
"controller"=>"my_controller", "action"=>"update"} permitted: false>

Все они попадают в контроллер в виде строк, но часы анализируются до json (с использованием JSON.parse), что приводит к чему-то вроде:

* Например, 1006 *

Часы - часы работы магазина. Он разделен днями недели. И каждый день не может иметь значения для дня, иметь одно значение или два. После проанализированных часов получается массив sh, и эти массивы могут быть пустыми или иметь один или два массива.

Моя проблема заключается в разрешении этого параметра часа при использовании params.require(:company).permit(). Я пробовал много разных способов, таких как:

  • params.require(:company).permit(:description, : email_address, :hours)
  • params.require(:company).permit(:description, : email_address, hours: {})
  • params.require(:company).permit(:description, : email_address, hours: [])
  • params.require(:company).permit(:description, : email_address, hours: { [sun: [], mon: [], tue: [], wed: [], thu: [], fri: [], sat: [] })
  • params.require(:company).permit(:description, : email_address, hours: [ [sun: [], mon: [], tue: [], wed: [], thu: [], fri: [], sat: [] ])
  • и другие

но это не удается или просто разрешается без какого-либо содержания, например:

<ActionController::Parameters {"description"=>"description", 
"email_address"=>"contact@gmail.com",
"hours"=><ActionController::Parameters {"sun"=>[], "mon"=>[], "tue"=>[], 
"wed"=>[], "thu"=>[], "fri"=>[], "sat"=>[]} permitted: true>} permitted: true>

Спасибо!

1 Ответ

0 голосов
/ 24 января 2020

Rails фактически не имеет синтаксиса для внесения в белый список вложенных массивов , насколько я знаю .

Это будет:

params.require(:company)
      .permit(:description, :email_address, hours: { mon: [] })

разрешить любое скалярное значение в company[:hours][:mon]. однако массив не является одним из разрешенных скалярных типов :

[ String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, ActionDispatch::Http::UploadedFile, Rack::Test::UploadedFile ]

, что объясняет, почему значения «отбрасываются». Я не думаю, что rails знает, что делать с permit(hours: { mon: [[]] }).

Но этого довольно легко избежать, если просто исправить входящий JSON или преобразовать его в Ruby.

json = if params[:company][:hours].present?
  # @todo handle JSON parsing errors
  # use each_with_object instead if your Ruby is older than 2.4
  JSON.parse(params[:company][:hours])
    &.transform_values { |v| v.empty? ? v : v.first } 
end
params.merge(
  hours: json
).permit(
   :description, :email_address, 
   hours: { sun: [], mon: [], tue: [], wed: [], thu: [], fri: [], sat: [] }
)

Это работает, так как "mon"=>[["09:00", "16:00"]] преобразуется в "mon"=>["09:00", "16:00"], а "09:00", "16:00" - строки и, следовательно, допустимые скалярные значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...