我有一个这样的订单模型:
class Order < ActiveRecord::Base
belongs_to :service_address, class_name: 'Address'
belongs_to :billing_address, class_name: 'Address'
accepts_nested_attributes_for :service_address, allow_destroy: true
accepts_nested_attributes_for :billing_address, allow_destroy: true
end
class Address < ActiveRecord::Base
end
我正在努力使嵌套表单工作,以允许我以相同的形式添加两个地址。订单的params部分是这样的:
params.require(:order).permit(:contract_id, :billing_address_id, :service_address_id, :valid_from, :valid_to, :contact_person_id, :billing_mode,
service_address: [:city_id, :street_id, :number, :block, :entrance, :floor, :apartment, :_destroy],
billing_address: [:city_id, :street_id, :number, :block, :entrance, :floor, :apartment, :_destroy])
我的创建动作是这样的:
@order = Order.new(order_params)
@order.service_address = Address.new(params[:order][:service_address])
@order.billing_address = Address.new(params[:order][:billing_address])
以这种方式提交时,表单无法验证,billing_address的所有字段都会突出显示为不完整。
如果我使用service_address_params
和billing_adress_params
,我会收到错误undefined local variable or method 'service_address_params'
我被困在这里两天,所以任何帮助都会受到赞赏。
编辑:new
def new
@order = Order.new
@order.service_address = Address.new
@order.billing_address = Address.new
end
编辑:form
<%= simple_form_for @order, data: {validate: 'parsley'} do |f| %>
<%= f.input :contract_id, as: :hidden, :input_html => { :value => @contract_id } %>
<%= f.input :same_billing_address, as: :hidden, :input_html => { :value => 0 } %>
<%= f.error_notification %>
<%= render :partial => 'order_data', :locals => { f: f } %>
<%= render :partial => 'service_address' %>
<%= render :partial => 'billing_address' %>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
地址的部分内容:
<%= simple_fields_for :service_address do |sa| %>
<div class="form-inputs" id="inputs-step2">
<%= sa.input :city_id, label: 'Oras', collection: @cities, input_html: { 'data-parsley-group' => "block2", :required => true, id: 'service_address_city_id' } %>
<%= sa.input :street_id, label: 'Strada', collection: @streets, input_html: { 'data-parsley-group' => "block2", :required => true, id: 'service_address_street_id' } %>
<%= sa.input :number, label: 'Numar', input_html: { 'data-parsley-group' => "block2", :required => true } %>
<%= sa.input :block, label: 'Bloc' %>
<%= sa.input :entrance, label: 'Scara' %>
<%= sa.input :floor, label: 'Etaj' %>
<%= sa.input :apartment, label: 'Apartament' %>
</div>
<% end %>
结算地址部分:
<%= simple_fields_for :billing_address do |ba| %>
<div class="form-inputs" id="inputs-step3">
<%= ba.input :city_id, label: 'Oras', collection: @cities, input_html: { 'data-parsley-group' => "block3", :required => true, id: 'billing_address_city_id' } %>
<%= ba.input :street_id, label: 'Strada', collection: @streets, input_html: { 'data-parsley-group' => "block3", :required => true, id: 'billing_address_street_id' } %>
<%= ba.input :number, label: 'Numar', input_html: { 'data-parsley-group' => "block3", :required => true } %>
<%= ba.input :block, label: 'Bloc' %>
<%= ba.input :entrance, label: 'Scara' %>
<%= ba.input :floor, label: 'Etaj' %>
<%= ba.input :apartment, label: 'Apartament' %>
</div>
<% end %>
params hash:
--- !ruby/hash:ActionController::Parameters
utf8: ✓
authenticity_token: nZvowtR+Iwo/Rt420w55ZSzNtiZCrjga57dSimDPdg0=
order: !ruby/hash:ActionController::Parameters
contract_id: ''
same_billing_address: '0'
valid_from: '2013-08-04'
months: '12'
billing_mode: '1'
service_address: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
city_id: '1'
street_id: '19'
number: '1'
block: '1'
entrance: '1'
floor: '1'
apartment: '1'
billing_address: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
city_id: '1'
street_id: '19'
number: '2'
block: '2'
entrance: '2'
floor: '2'
apartment: '2'
commit: Create Order
action: create
controller: orders
答案 0 :(得分:1)
首先,将accepts_nested_attributes_for
与belongs_to
一起使用是痛苦,而且非常棘手。其次,有很多错误。 code.I将逐一解释。
错误#1
您的new
方法应该是这样的
def new
@order = Order.new
@order.build_service_address
@order.build_billing_address
end
在create
方法中,您不需要这些行,请将其删除。
@order.service_address = Address.new(params[:order][:service_address])
@order.billing_address = Address.new(params[:order][:billing_address])
错误#2
您的order_params
方法应该是这样的
def order_params
params.require(:order).permit(:contract_id, :billing_address_id, :service_address_id, :valid_from, :valid_to, :contact_person_id, :billing_mode,service_address_attributes: [:city_id, :street_id, :number, :block, :entrance, :floor, :apartment, :_destroy],billing_address_attributes: [:city_id, :street_id, :number, :block, :entrance, :floor, :apartment, :_destroy])
end
请注意更改service_address_attributes
和billing_address_attributes
错误#3
您没有将locals
传递给service_address
和billing_address
部分内容。
这些行
<%= render :partial => 'service_address' %>
<%= render :partial => 'billing_address' %>
应该是这样的
<%= render :partial => 'service_address',:locals => { f: sa }%>
<%= render :partial => 'billing_address',:locals => { f: ba } %>
<强>更新强>
尝试在partials
main form
<%= f.simple_fields_for :service_address do |sa| %>
<%= render :partial => 'service_address',:locals => { f: sa }%>
<% end %>
<%= f.simple_fields_for :billing_address do |ba| %>
<%= render :partial => 'billing_address',:locals => { f: ba } %>
<% end %>
然后更改service_address
和billing_address
partials
中的代码
#_service_address.html.erb
<div class="form-inputs" id="inputs-step2">
<%= f.input :city_id, label: 'Oras', collection: @cities, input_html: { 'data-parsley-group' => "block2", :required => true, id: 'service_address_city_id' } %>
<%= f.input :street_id, label: 'Strada', collection: @streets, input_html: { 'data-parsley-group' => "block2", :required => true, id: 'service_address_street_id' } %>
<%= f.input :number, label: 'Numar', input_html: { 'data-parsley-group' => "block2", :required => true } %>
<%= f.input :block, label: 'Bloc' %>
<%= f.input :entrance, label: 'Scara' %>
<%= f.input :floor, label: 'Etaj' %>
<%= f.input :apartment, label: 'Apartament' %>
</div>
#_billing_address.html.erb
<div class="form-inputs" id="inputs-step3">
<%= f.input :city_id, label: 'Oras', collection: @cities, input_html: { 'data-parsley-group' => "block3", :required => true, id: 'billing_address_city_id' } %>
<%= f.input :street_id, label: 'Strada', collection: @streets, input_html: { 'data-parsley-group' => "block3", :required => true, id: 'billing_address_street_id' } %>
<%= f.input :number, label: 'Numar', input_html: { 'data-parsley-group' => "block3", :required => true } %>
<%= f.input :block, label: 'Bloc' %>
<%= f.input :entrance, label: 'Scara' %>
<%= f.input :floor, label: 'Etaj' %>
<%= f.input :apartment, label: 'Apartament' %>
</div>