【问题标题】:accept multiple models with a form用一个表格接受多个模型
【发布时间】:2016-05-18 09:06:17
【问题描述】:

我有一个供应商名称和电子邮件的基本表单设置。我想将我的地址属性嵌套到此表单中,但我不断收到以下错误

不允许的参数:地址

class Supplier < ActiveRecord::Base
  has_many :addresses, dependent: :destroy, as: :addressable    
  accepts_nested_attributes_for :addresses
end

class Address < ActiveRecord::Base
  belongs_to :addressable, polymorphic: true
  belongs_to  :supplier
end

class SuppliersController < ApplicationController

  def allowed_params
    params.require(:supplier).permit(:name, :email, {:address_attributes => [:first_name, :last_name, :address1, :address2, :city, :zip_code, :country_id]})
  end
end

供应商表格

%fieldset#admin-supplier-names.span-12
  %label Name
  = form.text_field :name
  %label Email
  = form.text_field :email

= form.fields_for :address do |address_fields|
  %li= address_fields.text_field :first_name, placeholder: :first_name.upcase, value: current_user.first_name
  %li= address_fields.text_field :last_name, placeholder: :last_name, value: current_user.last_name
  %li= address_fields.text_field :address1, placeholder: :address_1
  %li= address_fields.text_field :address2, placeholder: :address_2
  %li= address_fields.text_field :city, placeholder: :city
  %li= address_fields.text_field :zip_code, placeholder: :post_code
  %li=address_fields.select   :country_id, select_countries, :include_blank => true

【问题讨论】:

  • 供应商模型中的关联是has_many :addresses?
  • @Pavan 我有has_many :addresses, dependent: :destroy, as: :addressable
  • 如果您使用了 'belongs_to :addressable, :polymorphic => true' 那么为什么要使用 'belongs_to :supplier' ,我的意思是为什么要同时使用它们,如果一个可以满足您的目的?
  • 你为什么不用茧? github.com/nathanvda/cocoon :)

标签: ruby-on-rails forms nested-forms strong-parameters


【解决方案1】:

不允许的参数:地址

使用您的关联,您需要将fields_forallowed_params 中的address 更改为addresses

= form.fields_for :addresses do |address_fields|

并且在控制器的allowed_params

def allowed_params
  params.require(:supplier).permit(:name, :email, :addresses_attributes => [:first_name, :last_name, :address1, :address2, :city, :zip_code, :country_id])
end

【讨论】:

  • 现在地址字段没有随着该更改出现
  • 我还注意到,当参数通过它们仍然作为地址而不是地址属性的形式传输时
【解决方案2】:

supplieraddress 之间的关联声明与表单代码不同步。

如果您的 supplier 只能有一个 address,则在适用的情况下使用以下代码更新您的代码:

class Supplier < ActiveRecord::Base
  has_one :address, as: :addressable, dependent: :destroy
  accepts_nested_attributes_for :address
end

class Address < ActiveRecord::Base
  belongs_to :addressable, polymorphic: true
end

class SuppliersController < ApplicationController

  def new
    @supplier = Supplier.new
    @supplier.build_address
  end

  def edit
     @supplier = Supplier.find(params[:id])
     @supplier.build_address if @supplier.address.nil?
  end

  def allowed_params
    params.require(:supplier).permit(:name, :email, address_attributes: [:first_name, :last_name, :address1, :address2, :city, :zip_code, :country_id])
  end
end

%fieldset#admin-supplier-names.span-12
  %label Name
  = form.text_field :name
  %label Email
  = form.text_field :email

= form.fields_for :address do |address_fields|
  %li= address_fields.text_field :first_name, placeholder: :first_name.upcase, value: current_user.first_name
  %li= address_fields.text_field :last_name, placeholder: :last_name, value: current_user.last_name
  %li= address_fields.text_field :address1, placeholder: :address_1
  %li= address_fields.text_field :address2, placeholder: :address_2
  %li= address_fields.text_field :city, placeholder: :city
  %li= address_fields.text_field :zip_code, placeholder: :post_code
  %li=address_fields.select   :country_id, select_countries, :include_blank => true

但如果您的 supplier 可以有多个 addresses,则在适用的情况下使用以下代码更新您的代码:

class Supplier < ActiveRecord::Base
  have_many :addresses, as: :addressable, dependent: :destroy
  accepts_nested_attributes_for :addresses
end

class Address < ActiveRecord::Base
  belongs_to :addressable, polymorphic: true
end

class SuppliersController < ApplicationController

  def new
    @supplier = Supplier.new
    3.times { @supplier.addresses.build } #setup as many as you want
  end

  def edit
     @supplier = Supplier.find(params[:id])
     addresses_count = (3 - @supplier.addresses.count) 
     addresses_count.times { @supplier.addresses.build }
  end

  def allowed_params
    params.require(:supplier).permit(:name, :email, addresses_attributes: [:first_name, :last_name, :address1, :address2, :city, :zip_code, :country_id])
  end
end

%fieldset#admin-supplier-names.span-12
  %label Name
  = form.text_field :name
  %label Email
  = form.text_field :email

= form.fields_for :addresses do |address_fields|
  %li= address_fields.text_field :first_name, placeholder: :first_name.upcase, value: current_user.first_name
  %li= address_fields.text_field :last_name, placeholder: :last_name, value: current_user.last_name
  %li= address_fields.text_field :address1, placeholder: :address_1
  %li= address_fields.text_field :address2, placeholder: :address_2
  %li= address_fields.text_field :city, placeholder: :city
  %li= address_fields.text_field :zip_code, placeholder: :post_code
  %li=address_fields.select   :country_id, select_countries, :include_blank => true

请参阅StrongParametersFormBuilder 了解更多信息。

【讨论】:

  • 这是否适用于编辑从未创建过地址的供应商?
  • 应该,因为地址/地址是在新建和编辑操作中构建的。
  • 很有趣,因为它似乎只适用于新的,当我去选择对没有地址的现有供应商进行编辑时,不会显示表单字段
  • 您最终使用/测试了哪个选项? supplier has_one addresssupplier has_many addresses?
  • 您应该包含一个指向 gist 的链接,其中包含您更新的模型、控制器和视图代码,否则很难判断问题出在哪里,因为我仔细检查了提案并且一切正常。
【解决方案3】:

请查看并更新您的代码,如下所示 -:

  #-----controller----
  # GET /suppliers/new
 def new
  @supplier = Supplier.new
  @supplier.addresses.new
 end

 def allowed_params
   params.require(:supplier).permit(:name, :addresses_attributes=>  [:city]) # you can pass all your fields inside this array, i have tested for only one field i.e city.
 end

#-----update form field for nested attribute as shown below, append this inside your form(form_for(@suppier))
 <%= f.fields_for :addresses do |addr| %>
   <div>
     <%= addr.label :city %>
     <%= addr.text_field :city %>
   </div>
 <% end %>

您的代码的其余部分都很好,只需进行上述更改,您就可以开始了... :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 2018-12-19
    • 2017-10-10
    相关资源
    最近更新 更多