嵌套属性中的嵌套属性

Nested Attributes in Nested Attributes

Devise 3.5.2 & Rails 4.2.3

大家好

我对这个感到无能为力!

我正在尝试在我的设计注册表单的嵌套属性中添加嵌套属性。

基本上,用户输入他们的联系信息 - Name/Phone(这已经很有效了)。联系人字段是使用联系人模型中的嵌套属性构建的。

但是,我还希望他们输入 5 "zones",它们嵌套在所有权模型中。 Zone 模型包含一个 "zip" 列。我试图获得 5 个盒子,它们将在区域 table 中生成 5 行。我无法在我的表单上输入任何区域。

所以:

Sign Up!

First Name: <input>
Last Name: <input>
Phone: <input>
Zips: <input> <input> <input> <input> <input>
Email: <input>
Password: <input>
...<etc>...

             MEMBER
         ______|___________________
        |            |             |
     CONTACT      OWNERSHIP    (columns)
        |         ___|___________________________
    (columns)    |       |       |       |       |
               ZONE     ZONE    ZONE    ZONE    ZONE
                 |       |       |       |       |
             (column)(column)(column)(column)(column)

会员模型:

class Member < ActiveRecord::Base

  belongs_to :role
  has_one :contact
  has_one :ownership
  has_many :zones, through: :ownership

  accepts_nested_attributes_for :contact, :ownership, :zones

(联系方式为空)

所有权模型:

class Ownership < ActiveRecord::Base
  has_many :zones

  accepts_nested_attributes_for :zones
end

区域模型:

class Zone < ActiveRecord::Base
  belongs_to :ownership
end

注册控制器:

  def new
    build_resource({contact_attributes: {}, ownership_attributes: {zones_attributes: {}}})
    respond_with self.resource
  end

注册#new 视图:

<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <%= f.fields_for :contact do |cf| %>

    <div class="field">
      <%= cf.label :first_name %><br />
      <%= cf.text_field :first_name, autofocus: true %>
    </div>

    <div class="field">
      <%= cf.label :last_name %><br />
      <%= cf.text_field :last_name %>
    </div>

    <div class="field">
      <%= cf.label :phone %><br />
      <%= cf.text_field :phone %>
    </div>
  <% end %>
  <% if apply_domain? %>
    <%= f.label 'Zips' %>
    <%= f.fields_for :ownership do |of| %>
      <%= of.fields_for :zones do |zf| %>
        <div class="field">
          <%= zf.text_field :zip %>
        </div>
        <div class="field">
          <%= zf.text_field :zip %>
        </div>
        <div class="field">
          <%= zf.text_field :zip %>
        </div>
        <div class="field">
          <%= zf.text_field :zip %>
        </div>
        <div class="field">
          <%= zf.text_field :zip %>
        </div>
      <% end %>
    <% end %>
  <% end %>

...
~~~~~~~~~~~~

数据库迁移:

class CreateZones < ActiveRecord::Migration
  def change
    create_table :zones do |t|
      t.string :zip
      t.references :ownership

      t.timestamps null: false
    end
  end
end

~~~~

class CreateContacts < ActiveRecord::Migration
  def change
    create_table :contacts do |t|
      t.string :first_name
      t.string :last_name
      t.string :phone
      t.date :dob
      t.string :gender
      t.string :street
      t.string :city
      t.string :state
      t.string :zip
      t.string :referrer

      t.references :member

      t.timestamps null: false
    end
  end
end

~~~~

class CreateOwnerships < ActiveRecord::Migration
  def change
    create_table :ownerships do |t|
      t.references :member

      t.timestamps null: false
    end
  end
end

~~~~

class AddOwnershipIdToMember < ActiveRecord::Migration
  def change
      add_reference :members, :ownership, index: true
  end
end

~~~~

您不需要在视图中重复 :zip 文本字段 5 次。你只需要写

    <%= f.fields_for :ownership do |of| %>
      <%= of.fields_for :zones do |zf| %>
        <div class="field">
          <%= zf.text_field :zip %>
        </div>
      <% end %>
    <% end %>

并在您的控制器中创建对象的新实例,例如

resourсe.build_ownership
(1..5).each { resourсe.ownership.zones.new }

但是有一个问题,所有权没有任何id,所以区域不能关联到它。因此,您需要在 create 操作中处理它。