Rails - 嵌套表单fields_for not rendering

时间:2012-09-16 09:27:05

标签: ruby-on-rails nested-forms

我有两个在has_one / belongs_to关联中链接的模型;分别是Computer和Ipv6Address。

我已经预先填充了Ipv6Address表,其中包含了我希望它拥有的所有条目,现在我需要在计算机上创建一个下拉列表新/编辑表单以从Ipv6中选择一个项目以将其与。 需要预先填充这个的原因是计算机可以将预定义的IPv6范围与它们相关联,并且我希望最终用户能够轻松地从列表中盲目地选择某些内容而不需要理解为什么他们这样做;但是要给那些知道什么是机会选择他们想要的人。

到目前为止,我所看到的所有内容似乎只在您在新表单上同时创建两个对象然后编辑它们时才起作用。

我已经尝试按照我在网上找到的示例设置我的MVC,并检查出类似主题的其他stackoverflow问题。

电脑型号:

class Computer < ActiveRecord::Base
  has_one :ipv6_address
  accepts_nested_attributes_for :ipv6_address
  ...

Ipv6Address模型:

class Ipv6Address < ActiveRecord::Base
  attr_accessible :computer_id, :ip_address
  belongs_to :computer
  ...

电脑控制器:

class ComputersController < ApplicationController
  def new
    @computer = Computer.new
    @ipv6s = Ipv6Address.where('computer_id IS NULL').limit(5)
  end

  def edit
    @computer = Computer.find(params[:id])
    @ipv6s = Ipv6Address.where('computer_id = #{@computer.id} OR computer_id IS NULL').order('computer_id DESC').limit(5)
  end

计算机新表格:

<%= simple_form_for( @computer ) do |f| %>
  <%= f.fields_for :ipv6_address do |v6| %>
    <%= v6.input :ipv6_address, :collection => @ipv6s %>
  <% end %>
  <% f.button :submit %>
<% end %>

当这个新表单呈现时,没有包含ipv6_address的输入字段,但不会抛出任何错误。我已经检查了渲染页面的来源,没有引用“ipv6”。

如果我将fields_for更改为:

<%= f.fields_for :ipv6_address, @ipv6s do |v6| %>

然后我在页面上出现多个下拉选择字段,一个用于@ipv6s中的每个对象,每个对象包含@ ipv6s中的完整对象列表。

1 个答案:

答案 0 :(得分:1)

您似乎不想创建新的ivp6_addresses,所有您想要做的就是在创建计算机时建立计算机和地址之间的关联。您可以使用第三个表来定义所有计算机/ ivp6关系,也可以稍微调整模型定义。以下是如何在不添加第三个表的情况下执行此操作。

关系可能看起来有些倒退,但是rails会通过在计算机表中找到ivp6_address_id来找到ipv6关联。如果是相反的方式,你需要为每台创建的计算机创建一个新的ivp6_address,这不是你想要的。确保计算机表中有适当的id列用于ivp6_address_id或您要使用的任何外键。

电脑型号:

class Computer < ActiveRecord::Base
  belongs_to :ipv6_address
  ...

Ipv6Address模型:

class Ipv6Address < ActiveRecord::Base
  attr_accessible :ip_address
  has_many :computers
  ...

然后删除计算机表单中的嵌套字段,并在提交表单时添加以下行以构建关联。

<%= form_for( @computer ) do |f| %>
   <!--All the computer fields you need-->
  <%= collection_select(:computer, :ipv6_address_ids, Ipv6Address.all, :id, :ip_address, {}, { :multiple => true } )%>
  <% f.button :submit %>
<% end %>