我有一个如下的模型结构:
class Client
belongs_to :lead
accepts_nested_attributes_for :lead
end
class Lead
has_one :client
has_many :defense_practices, through: :some_join_model, source: :practice, source_type: "DefensePractice"
accepts_nested_attributes_for :defense_practices
end我有一个表单结构如下:
<%= form_for @client do |f| %>
<%= f.fields_for :leads do |lead_builder|
<%= f.fields_for defense_practices do |practice_builder|
<%= practice_builder.text_field :some_field %>
<% end %>
<% end %>
<% end %>在params散列中正确提交数据:
Parameters: {
"client"=>{
"lead_attributes"=>
{"id"=>"45",
"defense_practices_attributes"=>
{"0"=>{
"some_field"=>"some_value",
"id"=>"52"
},
"4"=>{
"some_field"=>"some_value"
}
}
}
}
}第二个实践是通过javascript添加的,使用的技术与railscasts嵌套模型表单中使用的技术相同。
在创建操作中初始化模型时,通过javascript添加的防御实践(由于上面的散列中缺少id属性而未保存)不会被初始化:
def create
@client = Client.new client_profile_params
puts @client.lead.defense_practices.size # => 1
end
def client_profile_params
params[:client].permit!
end特别注意:在Client模型中,我必须覆盖lead_attributes=,因为我有一个未保存的客户端模型和一个已保存的lead模型,如果我没有覆盖,则rails会抱怨: had‘t find Lead with ID=46 for Client with ID=。
def lead_attributes=(params)
if params[:id].present?
lead = Lead.find(params[:id])
self.lead = lead
else
super
end
end它应该初始化两个防御实践。但它只初始化了已经与该线索关联的防御练习。它没有将新的防御实践添加到协会中。我做错了什么?
发布于 2014-11-14 08:31:22
这就是我所说的连锁反应。Rails的一个限制是使用黑客,这会释放大量蠕虫。因为Lead是在客户端之前创建的,所以我无法使用现有Lead保存客户端。因此,我不得不在我的模型中覆盖Rails核心lead_attributes=方法。嗯,通过这样做,它绕过了很多Rails内部。我能够通过使用update_attributes并传入params散列来获取它:
def lead_attributes=(params)
if params[:id].present?
lead = Lead.find(params[:id])
lead.update_attributes params
self.lead = lead
else
super
end
end不幸的是,这引发了新的问题,但它确实解决了所提出的问题。
https://stackoverflow.com/questions/26920608
复制相似问题