我有5个模型,我需要创建一个独特的表单,可以为每个模型创建一个新的对象。模型是
Contract.rb
belongs_to :establishment
Establishment.rb
has_many :contracts
belongs_to :address
belongs_to :client
Address.rb
has_many :establishments
belongs_to :zip
Client.rb
has_many :establishments
Zip.rb
has_many :addresses要创建对象的表单是Contract的表单。
我的第一种方法是分别创建fields_for --其他模型,例如:
_form.html.erb
<%= form_for(@contract) do |f| %>
<% if @contract.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@contract.errors.count, "error") %> prohibited this contract from being saved:</h2>
...#fields for contract
<%= f.fields_for @client do |client|%>
<%=client.label 'Name'%><%=client.text_field :name%>
...#other fields for client
<%= f.fields_for @address do |address|%>
<%=address.label 'Street'%><%=address.text_field :street%>
...#other fields for address
<%=f.fields_for @zip do |zip|%>
<%=zip.label 'Code'%><%=zip.number_field :code%>
...#other fields for zip表单工作正常,得到了所有字段,但是在ContractController.rb上,我无法访问params上的地址、客户端和Zip字段。如果我使用@client = Client.create(params[:client]),它将不会得到一个错误,但不会在模型上创建一个对象。我意识到,params[:client] (以及其他人认为不是合同的)是零的。然后我使用params[:contract][:client]得到了错误ForbiddenAttributesError..。
所以,我决定改变方法,开始用多级nested_attributes来思考,但我仍然没有.
我已经把模特改成:
Contract.rb
belongs_to :establishment
accepts_nested_attributes_for :establishment
has_one :address, through: :establishment
accepts_nested_attributes_for :address
has_one :zip, through: :address
accepts_nested_attributes_for :zip
has_one :client, :through => :establishment
accepts_nested_attributes_for :client在我做的控制器上
ContractController.rb
def new
@contract = Contract.new
@establishment = @contract.build_establishment
@address = @establishment.build_address
@zip = @address.build_zip
@client = @establishment.build_client
end但是现在表单没有用于Client, Address and Zip的字段
可以创建这种类型的表单吗?
发布于 2014-06-30 23:56:57
-编辑的答案--删除_attributes在[:contract][:client_attributes][:...] (和:zip和:address)处的地址
G.B.差点就拿到了,但这还不够。
回到第一种方法,在阅读了这个文章之后,我做了以下更改:
Contract
_form.html.erb
<%= form_for(@contract) do |f| %>
<% if @contract.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@contract.errors.count, "error") %> prohibited this contract from being saved:</h2>
...#fields for contract
<%= f.fields_for :client, @client do |client|%>
<%=client.label 'Name'%><%=client.text_field :name%>
...#other fields for client
<%= f.fields_for :address, @address do |address|%>
<%=address.label 'Street'%><%=address.text_field :street%>
...#other fields for address
<%=f.fields_for :zip, @zip do |zip|%>
<%=zip.label 'Code'%><%=zip.number_field :code%>
...#other fields for zip因此,它必须是f.fields_for @client do |client| (地址和zip相同),而不是f.fields_for :client, @client do |client|。
论ContractController
def new
@contract = Contract.new
@client = Client.new
@address = Address.new
@zip = Zip.new
end
def create
@contract = Contract.new(contract_params)
if !Zip.exists?(:cod_postal1 => params[:contract][:zip][:cod_postal1], :cod_postal2 => params[:contract][:zip][:cod_postal2])
create_zip
elsif
@zip = Zip.where(:cod_postal1 => params[:contract][:zip][:cod_postal1], :cod_postal2 => params[:contract][:zip][:cod_postal2])
end
create_client
create_address
@address.zip = @zip
@establishment = Establishment.new(:sede => true)
@establishment.address = @address
@establishment.client = @client
@client.save
@address.save
@establishment.save
@contract.establishment = @establishment
respond_to do |format|
if @contract.save
...
end
def create_client
@client = Client.create(
:numero => params[:contract][:client][:numero],
...#other client fields
)
end
def create_zip
@zip = Zip.create(
:distrito => params[:contract][:zip][:distrito],
:concelho => params[:contract][:zip][:concelho],
...#other zip fields
)
end
def create_address
@address = Address.create(
:rua => params[:contract][:address][:rua],
...#other address fields
)
end这起作用很大。在一个有一个提交按钮的表单中,创建了不同的模型
发布于 2014-06-30 05:23:35
如果要使用accepts_nested_attributes_for,请从API接口中记住这一点:
“嵌套属性允许您通过父属性在关联记录上保存属性”
因此,这样说是无效的:
Class Contract #child class
belongs_to :establishment
accepts_nested_attributes_for :establishment因为Contract是child。不是Parent。
正确的做法是:
Class Establishment # parent class
has_many :contracts
accepts_nested_attributes_for :contracts然后在Establishments控制器params中添加:
contracts_attributes: [:id, attribute1, attribute2] #不要忘记添加:id
对所有其他模型都采用相同的方法。阅读API接口中的示例
https://stackoverflow.com/questions/24482021
复制相似问题