Rails 4.1 Вложенные атрибуты и поля для получения неразрешенных параметров без сохранения

Исследование: Бета-версия Rails 4.0, fields_for не принимает множественное число model_name в ассоциации "один ко многим", Вложенные атрибуты Rails 4 с fields_for Не сохранять в базу данных

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

class AdultsController < ApplicationController
...
  def update
    authorize @user
    respond_to do |format|
      if @user.update_attributes(user_params)
        format.html { redirect_to unit_adult_path(@unit, @user), notice: "#{@user.full_name} was successfully updated." }
      else
        format.html { render action: 'edit' }
      end
    end
  end

  def user_params
    params.require(:adult).permit(:first_name, :last_name, phones_attributes: [])
  end
end

И мои модели настроены правильно

class User < ActiveRecord::Base
  has_many :phones, dependent: :destroy
  accepts_nested_attributes_for :phones, allow_destroy: true, reject_if: proc { |a| a["number"].blank? }
end

class Phone < ActiveRecord::Base
  belongs_to :user, touch: true
end

И вид

# adult/_form.html.haml
= bootstrap_form_for [@unit, @user] do |f|
  = f.text_field :first_name, control_col: 'col-md-4'
  = f.text_field :last_name, control_col: 'col-md-4'

  = f.fields_for :phones do |f_phone|
    = f_phone.form_group do
      = f_phone.select :kind, options_for_phones, hide_label: true, layout: :default
      = f_phone.phone_field :number, hide_label: true, layout: :default
      = f_phone.check_box :_destroy, label: 'remove'

Но когда я отправляю форму пользователя для сохранения

Started PATCH "/units/2/adults/1" for 127.0.0.1 at 2014-07-11 15:20:17 -0700
Processing by AdultsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"pDjDVSiEs5qqHLqnbxQMeGWDOUGvhXPPvgyRGmitmps=", "adult"=>{"first_name"=>"Karl", "last_name"=>"Smith", "phones_attributes"=>{"0"=>{"kind"=>"other", "number"=>"888.1212", "_destroy"=>"0", "id"=>"173"}, "1"=>{"kind"=>"mobile", "number"=>"888.1212", "_destroy"=>"0", "id"=>"174"}} }, "commit"=>"Update Adult", "unit_id"=>"2", "id"=>"1"}

Unpermitted parameters: phones_attributes

Я не понимаю, почему вложенные данные отклоняются строгой оценкой параметра. Мне выглядит правильно.

Единственное, что я заметил, это то, что данные параметров для значения «phones_attributes» представляют собой ХЕШ, а не МАССИВ. В user_params, phone_attributes: [] выглядит так, будто ожидает МАССИВ. Поэтому я изменил его на HASH.

  def user_params
    params.require(:adult).permit(:first_name, :last_name, phones_attributes: {})
  end

Но теперь я получаю следующую ошибку.

Unpermitted parameters: 0, 1

Поэтому я попытался указать имена полей в массиве «phones_attributes».

def user_params
    params.require(:adult).permit(:first_name, :last_name, phones_attributes: [:id, :kind, :number])
end

И я все еще получаю.

Unpermitted parameters: phones_attributes

Я знаю, что должен упустить что-то маленькое, но я не могу найти свою ошибку.

РЕДАКТИРОВАТЬ: все мои формы вложенных атрибутов не работают. Не уверен на 100%, когда они остановились, но те, что работали раньше, больше не работают и не модифицировались.


person Karl    schedule 11.07.2014    source источник


Ответы (1)


Разобрался с этим. Я использовал javascript для копирования полей телефона (вид, номер), чтобы сделать новый набор входных данных доступным для ввода. Сценарий добавлял нечисловые символы в часть идентификатора поля, и это заставляло рельсы игнорировать все отправленные атрибуты phone_attributes.

Для следующего человека, который придет...

Когда fields_for отображает поля, он будет индексировать каждое входное имя для уникальности, когда отправленные данные поста преобразуются в параметры. В приведенном ниже примере это числовое поле

<input id="adult_phones_attributes_0_number" name="adult[phones_attributes][0][number]" type="tel" value="7773331111">

будет выглядеть примерно так при преобразовании в параметры

"phones_attributes"=>{"0"=>{"number"=>"7773331111"}}

Хэш-ключ "0" происходит из индекса, созданного fields_for. Это часть имени "[0]".

В прошлых версиях рельсов, если хеш-ключ вложенных атрибутов params не был числом, пара k/v просто игнорировалась. Что ж, теперь с сильными параметрами (я предполагаю виновника) он отклонит весь хеш «phones_attributes».

Мой скрипт копировал поле ввода, выполняя регулярное выражение в html, чтобы изменить индекс «[0]» на случайное число. Но иногда он заменял бы его нецифровыми символами. И это вызывало проблему.

person Karl    schedule 12.07.2014
comment
Хэш-ключ указывает на идентификатор, и поэтому rails использует его, чтобы определить, имеете ли вы в виду новый или существующий телефон. Поэтому, если это было/не число, оно не игнорируется, а создает новую запись. Я предполагаю, что ваша проблема заключалась в следующем: когда вы добавляете нечисловые символы к числу, to_i все равно будет возвращать одно и то же число, и поэтому ваши новые строки будут сталкиваться в одну. - person nathanvda; 14.02.2016