嵌套属性中的嵌套属性

时间:2015-08-27 23:19:07

标签: ruby-on-rails ruby devise

Devise 3.5.2& Rails 4.2.3

大家好,

我觉得我的智慧结束了这个!

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

基本上,用户输入他们的联系信息 - 姓名/电话(这就像魅力一样)。联系人字段是使用Contact模型中的嵌套属性构建的。

但是,我还希望他们进入5个“区域”,这些区域嵌套在所有权模型中。 Zone模型包含“zip”列。我想获得5个在Zones表中生成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 view:

<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 %>

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

db migration:

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

~~~~

1 个答案:

答案 0 :(得分:1)

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

    <%= 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行动中处理此问题。