【问题标题】:Rails 4.2.4 / Devise - How to allow nested attributesRails 4.2.4 / 设计 - 如何允许嵌套属性
【发布时间】:2015-10-29 20:41:15
【问题描述】:

我在尝试使用 Devise 清除嵌套表单的某些参数时遇到了一些问题。这是我的代码,最后解释了我已经尝试过的内容。

我在 SO 中找到了一堆答案,但所有答案似乎都指向只放 :address_attributes => [:etc],但它对我不起作用。

用户模型

class User < ActiveRecord::Base

  has_many :addresses, dependent: :destroy
  has_many :phones, dependent: :destroy

  accepts_nested_attributes_for :addresses, allow_destroy: true
  accepts_nested_attributes_for :phones, allow_destroy: true

end

地址

class Address < ActiveRecord::Base
  belongs_to :user
end

电话

class Phone < ActiveRecord::Base
  belongs_to :user
end

形式

  .row
    .col-md-3
      %p 2. Complete seus dados pessoais
    .col-md-9
      = simple_form_for @user, url: user_registration_path, method: :patch, class: 'form-inline' do |f|
        = f.input :name, label: 'Nome Completo'
        = f.input :birth_date, label: 'Data de Nascimento', start_year: 1910
        = f.input :cpf, label: 'CPF'
        .row
          = f.simple_fields_for @user_phone do |ff|
            .col-md-4
              = ff.input :country_code, label: 'Código do País'
            .col-md-4
              = ff.input :area_code, label: 'DDD'
            .col-md-4
              = ff.input :number, label: 'Telefone'

        = f.simple_fields_for @user_address do |ff|
          = ff.input :zip_code, label: 'CEP'
          = ff.input :street, label: 'Rua'
          = ff.input :street_number, label: 'Número'
          = ff.input :district, label: 'Bairro'
          = ff.input :complement, label: 'Complemento'
          = ff.input :state_id, collection: @states, label: 'Estado'
          = ff.input :city_id, collection: @cities, label: 'Cidade'
        = f.submit 'Salvar'

设计注册控制器

class Users::RegistrationsController < Devise::RegistrationsController
    before_filter :configure_sign_up_params, only: [:create]
    before_filter :configure_account_update_params, only: [:update]

  def configure_account_update_params
    devise_parameter_sanitizer.for(:account_update) do |u| 
      # raise
      u.permit(:username, :name, :birth_date, :cpf, :phone_attributes =>    [:country_code, :area_code, :number], :address_attributes => [:zip_code, :street_number, :street, :district, :complement, :state_id, :city_id])
    end
  end

结束

日志:

    tarted PATCH "/users" for 127.0.0.1 at 2015-10-29 18:31:22 -0200
    Processing by Users::RegistrationsController#update as HTML
      Parameters: {"utf8"=>"✓", "authenticity_token"=>"CiXxFEc9zv6WAf5Ow/Kv8ZDU84lAsdFXmLP0IeDlxGKgbjdOzS2+IlZ3NVFlwDKohQz0ix7m0uXOUGEg2na1HA==", "user"=>{"name"=>"Teste", "birth_date(3i)"=>"29", "birth_date(2i)"=>"10", "birth_date(1i)"=>"2015", "cpf"=>"32323232", "phone"=>{"country_code"=>"55", "area_code"=>"3232", "number"=>"323232"}, "address"=>{"zip_code"=>"32212", "street"=>"dasdasdasdas", "street_number"=>"dasdasdasd", "district"=>"sdasdasdas", "complement"=>"asdasdasdsa", "state_id"=>"2", "city_id"=>"1"}}, "commit"=>"Salvar"}
      User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]
      User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."deleted_at" IS NULL AND "users"."id" = $1 LIMIT 1  [["id", 1]]
    Unpermitted parameters: phone, address
       (0.1ms)  BEGIN
       (0.1ms)  COMMIT
    Redirected to http://localhost:3000/
    Completed 302 Found in 26ms (ActiveRecord: 0.7ms)

如果它尝试放置 :address_attributes => [:etc],我会得到未经许可的参数。如果我只尝试:address => [:etc],我会得到“找不到用户的属性地址”。

我试过输入复数 (:addresses_attributes) 但它不起作用。

设计控制器已经在路由中配置,并允许我编辑模型本身的所有字段,问题仅在嵌套模型中。

谁能帮忙?

【问题讨论】:

    标签: ruby-on-rails ruby devise nested-attributes strong-parameters


    【解决方案1】:

    您遇到的主要问题是您的 fields_for 未正确初始化您的嵌套属性 - 参数应分别通过 phones_attributesaddresses_attributes

    因此,您最好使用以下方法:

    #config/routes.rb
    devise_for :users, controller: { registrations: "registrations" }
    
    #app/controllers/registrations_controller.rb
    class RegistrationsController < ApplicationController
       def new
         build_resource({})
         self.resource.phones.build
         self.resource.addresses.build
         respond_with self.resource
       end
    end
    

    那么在你看来:

    #app/views/registrations/new.haml
    ...
    = f.simple_fields_for :phones do |ff|
       ...
    = f.simple_fields_for :addresses do |ff|
       ...
    

    这应该设置正确的属性以通过您的模型传递。

    【讨论】:

    • 哇!我永远不会看到那个。非常感谢你!真的解决了!
    猜你喜欢
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多