【问题标题】:Nested Forms Rails嵌套表单 Rails
【发布时间】:2012-03-27 09:51:54
【问题描述】:

我有 2 个模型用户和地址。

class User < ActiveRecord::Base 
  has_many :addresses
  accepts_nested_attributes_for :addresses
end

class Address < ActiveRecord::Base
  belongs_to :user
end

我的控制器

  def new
    @user = User.new
    @user.addresses << Address.new
    @user.addresses << Address.new
  end

  def create
    @user = User.new(params[:user])
    if @user.save
      #do something
    else
      render 'new'
    end
  end

我的观点

 <%= form_for @user do |f| %>
     <%= f.label :name %>
     <%= f.text_field :name %>
       <%= f.fields_for :addresses do |a| %>
         <p> Home </p>
         <%= a.text_field :state %>
         <%= a.text_field :country%>
         <%= a.text_field :street %>
         <p> Work </p>
         <%= a.text_field :state %>
         <%= a.text_field :country%>
         <%= a.text_field :street %>
       <% end %>
     <% end %>
   <% end %>

我的问题是我只得到了参数中输入的最后一个州、国家、街道。

"addresses_attributes"=>{"0"=>{"street"=>"test", "state"=>"test",, "country"=>"test"},
"1"=>{"street"=>"", "state"=>"", "country"=>""}} 

另外,如果有更好的方法可以做到这一点,我将不胜感激。

【问题讨论】:

  • 只有最后一个是什么意思?您在此处显示的输出清楚地表明您正在接收两者。 address_attributes[0] 和addresses_attributes[1]
  • 是的,但我填写了所有字段,并且只发送了最后 3 个字段。
  • 示例:前 3 个字段用 'test0' 填充,后 3 个字段用 'test' 填充。

标签: ruby-on-rails ruby forms associations nested-forms


【解决方案1】:

rails API 表示fields_for 将自行重复地址集合中的每个元素。

我建议为您的地址添加一种标签(如工作、家庭等)。然后它应该自己工作。有了这个标签,当您想添加更多地址时,您会更加灵活。

   <%= f.fields_for :addresses, @user.addresses do |a| %>
     <p> <%= a.object.label %> </p>
     <%= a.text_field :state %>
     <%= a.text_field :country%>
     <%= a.text_field :street %>
   <% end %>

【讨论】:

  • 好的,我尝试了你所说的,我得到一个未定义的方法 `is_home_address' for nil:NilClass 错误,有什么想法吗?
  • 您能否提供更多信息?一些行号和围绕这个数字的代码?我发现总是很难猜出错误:P
  • 好的,我通过将表单包装在@user.addresses.each do |address| 中修复了错误。并将地址对象添加到 fields_for :addresses,address .... 现在我可以访问该对象 ... 但是参数更改了 params[:user][:address] 并且只发送了一个地址。
  • 嗯,你可以试试fields_for @user.adresses do |a|。并恢复您最近的更改。
  • 好吧,我照你说的做了,看来我只得到一个地址对象,但我在控制器中构建了 2 个对象...
【解决方案2】:

fields_for :addresses 已经为您完成了循环,因此您无需重复州、国家和街道。因此,在您的情况下,您可以添加新的字段地址类型,然后控制器应如下所示:

def new
  @user = User.new
  @user.addresses.build(address_type: 'Home')
  @user.addresses.build(address_type: 'Work')
end

然后是形式:

<%= form_for @user do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
    <%= f.fields_for :addresses do |a| %>
      <%= a.hidden_field :address_type %>
      <p><%= a.object.address_type %></p>
      <%= a.text_field :state %>
      <%= a.text_field :country%>
      <%= a.text_field :street %>
    <% end %>
  <% end %>
<% end %>

a.object 指的是地址对象。

【讨论】:

  • 好的,我尝试了你所说的,我得到一个未定义的方法 `is_home_address' for nil:NilClass 错误,有什么想法吗?
  • 您是否将 address_type 迁移到 db?当您访问表单时是否会发生该错误?我更新了答案以将隐藏字段添加到 address_type 以便它持久保存到数据库。如果仍然有问题,请尝试使用以下命令进行调试:.
  • 我认为您应该重新检查@user.save 中的代码。看起来有一些代码可以从用户那里删除地址。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 2020-02-21
  • 2016-04-04
  • 1970-01-01
相关资源
最近更新 更多