2015-10-20 112 views
1

我是新手,我正在创建一个带有addersses客户端的简单应用程序。从堆栈溢出社区获得一些建议和意见后,我decided to save addresses as a seperate modelRails - 自动创建相关模型

我现在试图在我的应用程序中实现这一点,但我有问题得到的地址从“新客户端”窗体正确保存。这里是我的代码到目前为止:

class Address < ActiveRecord::Base 
    belongs_to :client 
end 

class Client < ActiveRecord::Base 
    has_one :address 
    before_create :build_address, unless: Proc.new { |client| client.address } 
end 



<%= form_for(@client) do |f| %> 
    <% if @client.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@client.errors.count, "error") %> prohibited this client from being saved:</h2> 

     <ul> 
     <% @client.errors.full_messages.each do |message| %> 
     <li><%= message %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 

    <div class="field"> 
    <%= f.label :name %><br> 
    <%= f.text_field :name %> 
    </div> 
    <div class="field"> 
    <%= f.label :phone_number %><br> 
    <%= f.text_field :phone_number %> 
    </div> 

    <%= f.fields_for :address do |a| %> 
    <div class="field"> 
     <%= a.label :house_number %><br> 
     <%= a.number_field :house_number %> 
    </div> 
    <div class="field"> 
     <%= a.label :house_name %><br> 
     <%= a.text_field :house_name %> 
    </div> 
    <div class="field"> 
     <%= a.label :post_code %><br> 
     <%= a.text_field :post_code %> 
    </div> 
    <% end %> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 

<% end %> 

这样,客户端已成功创建,但地址记录是用空字段创建的。没有错误。

任何帮助将不胜感激。

感谢

+0

你有'accepts_nested_attributes_for:address'?你在'params.require(:client)'中有什么? –

回答

2

你需要accepts_nested_attributes_for

#app/models/client.rb 
class Client < ActiveRecord::Base 
    has_one :address 
    accepts_nested_attributes_for :address 
    before_create :build_address, unless: Proc.new { |client| client.address } 
end 

这将允许你做到以下几点:

#app/controllers/clients_controller.rb 
class ClientsController < ApplicationController 
    def new 
     @client = Client.new 
     @client.build_address 
    end 
end 

这应该为你工作。

+0

'build_address'不会运行两次吗? – max

+0

不是因为2个原因。 1)build_address仅在'new'(而不是'create')中明确调用,并且2)after_create回调有一个条件,在地址不存在的情况下阻止构建 –

2

首先 - 很少有情况下ActiveModel回调不会导致悲伤。通常把逻辑放入你的模型是一件好事 - 但只要你需要它们就可以运行回调,而不需要在无关的测试中进行回调几乎是不可能的。

在这种情况下,您只需构建地址,以便表单输入在您的新操作中预填充。没有其他理由让您的所有客户端实例始终拥有空地址记录。

所以不是我们会做这样的:

class Client < ActiveRecord::Base 
    has_one :address 
    accepts_nested_attributes_for :address 
end 

class ClientController < ApplicationController 
    def new 
    @client = Client.new 
    @client.build_address 
    end 

    def create 
    @client = Client.create(client_params) 
    # ... 
    end 

    def client_params 
    params.require(:client) 
      .permit(
      :name, :phone_number, 
      address_attributes: [:house_number, :house_name] 
     ) 
    end 
end 
+0

感谢您的回复。这给我一个错误: 未定义的方法'build_address'为零:NilClass – Craig

+0

编辑所以它应该工作 –

+0

原来是client.build_address不是@ client.address.build_address。再次感谢max – Craig