Rails使用has_one通过关系嵌套表单

时间:2013-02-28 22:46:43

标签: ruby-on-rails activerecord ruby-on-rails-3.2 nested-forms nested-attributes

我真的很难理解如何使用第二个模型连接的模型创建嵌套表单。我在SO上查了一个number of posts,尝试了很多方法,但无法弄明白,不过我觉得我差不多了。

我正在尝试以一种形式创建订阅,客户和客户的地址,但到目前为止,我只设法创建订阅和客户。我的地址有问题。

客户可以有多个订阅,但只有一个地址(暂时,无论如何)

我的(缩写)代码如下所示:

subscription.rb

class Subscription < ActiveRecord::Base

  belongs_to :customer
  has_one :address, through: :customer

  accepts_nested_attributes_for :customer, :address
  attr_accessible :customer_attributes, :address_attributes

customer.rb

class Customer < ActiveRecord::Base

  has_one :address
  has_many :subscriptions

  accepts_nested_attributes_for :address
  attr_accessible :address_attributes

address.rb

class Address < ActiveRecord::Base

  belongs_to :customer
  has_many :subscriptions, through: :customer

subscriptions_controller.rb

def new
  @subscription = Subscription.new    
  customer = @subscription.build_customer
  address = customer.build_address
  subscription_line_items = @subscription.subscription_line_items.build
end

订阅/ _form.html.erb

<%= form_for(@subscription) do |subscription_form| %>
  <% if @subscription.errors.any? %>
    <!-- Error stuff -->
  <% end %>

  <div class="field">
    <%= subscription_form.label :start_date %><br />
    <%= subscription_form.text_field :start_date %>
  </div>

  ...

  <h2>Customer Details</h2>
  <%= subscription_form.fields_for :customer do |customer_fields| %>
    <%= customer_fields.label :first_name %><br /> 
    <%= customer_fields.text_field :first_name %>
    ...
  <% end %>

  <h2>Address</h2>
  <%= subscription_form.fields_for :address do |address_fields| %>
    <%= address_fields.label :address_1 %><br /> 
    <%= address_fields.text_field :address_1 %>
    ...
  <% end %>

  <div class="actions">
    <%= subscription_form.submit %>
  </div>
<% end %>

我知道我的控制器代码正常工作,就像我直接在控制台中尝试它一样,我得到一个空的地址对象,但这并没有在表单中呈现,这让我相信我的模型代码仍然没有不对。

1 个答案:

答案 0 :(得分:1)

紫色,看你最新的问题:

Can't mass-assign protected attributes: customer, address

您需要在模型中添加这些属性,如:

attr_accessible :customer, :address