我是rails的新手,我正在创建一个带有addersses的客户端的简单应用。在从堆栈溢出社区获得一些建议和意见后,我decided to save addresses as a seperate model
我现在正在尝试在我的应用中实现此功能,但我在从“新客户端”表单中获取正确保存地址时遇到问题。这是我目前的代码:
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 :(得分: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
这应该适合你。
答案 1 :(得分: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