在我的应用中,我有联系人,其中有很多目标(目标属于联系人)。我使用嵌套表单为两个模型创建/更新数据,但是在创建/更新操作期间只保存第一个子目标,这可以从下面传递的参数中看出:
Started PATCH "/contacts/2" for 127.0.0.1 at 2014-05-11 19:10:40 -0400
Processing by ContactsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"wKgOPegIJOFyrrLAnbdD67qqATFXrPNqMIT7I/tpNfo=", "contact"=>{"name"=>"Steven Tyler", "title"=>"Manager", "company"=>"Dell", "email"=>"steve@dell.com", "notes"=>"cool guy", "goals_attributes"=>{"0"=>{"title"=>"goal1", "due_date(1i)"=>"2014", "due_date(2i)"=>"5", "due_date(3i)"=>"11", "notes"=>"fdfsd", "_destroy"=>"false", "id"=>"13"}}}, "commit"=>"submit", "id"=>"2"}
Contact Load (0.1ms) SELECT "contacts".* FROM "contacts" WHERE "contacts"."id" = ? LIMIT 1 [["id", 2]]
(0.1ms) begin transaction
Goal Load (0.3ms) SELECT "goals".* FROM "goals" WHERE "goals"."contact_id" = ? AND "goals"."id" IN (13) [["contact_id", 2]]
(0.1ms) commit transaction
Redirected to http://localhost:3000/contacts/2
以下是我的模特:
class Contact < ActiveRecord::Base
belongs_to :user
has_many :goals, dependent: :destroy
accepts_nested_attributes_for :goals, allow_destroy: true, reject_if: lambda {|attributes| attributes['title'].blank? && attributes['notes'].blank?}
validates_presence_of :user_id,:name,:title,:email
end
class Goal < ActiveRecord::Base
belongs_to :contact
validates_presence_of :title, :due_date
end
并且,Contacts控制器中的强参数:
def contact_params
params.require(:contact).permit(:name, :title, :company, :email, :notes, goals_attributes: [:title, :due_date, :notes, :contact_id, :_destroy, :id])
end
以下是使用的两种表格:https://gist.github.com/nowgeez/5fbe99e814330c1b371c 知道为什么只保存第一个目标,而不是在表格中创建任何其他后续目标?在此先感谢您的帮助。
答案 0 :(得分:3)
如文档中所述,使用正确的div嵌套非常重要。
所以在你的情况下你应该写:
<%= simple_form_for(@contact) do |f| %>
<%= f.input :name %>
<%= f.input :title %>
<%= f.input :company %>
<%= f.input :email %>
<%= f.input :notes %>
<h3>Goals:</h3>
<div id="goals">
<%= f.simple_fields_for(:goals) do |goal| %>
<%= render 'goal_fields', :f => goal %>
<% end %>
<div class="links">
<%= link_to_add_association 'add goal', f, :goals %>
</div>
</div>
<%= f.submit :submit %>
<% end %>
为清楚起见,我删除了错误块。 目标本身应该包含在div中,以便删除工作。
<div class="nested-fields>
<%= f.input :title %>
<%= f.input :due_date %>
<%= f.input :notes %>
<%= link_to_remove_association "remove goal", f %>
</div>
在旁注:我讨厌写erb,它更冗长,从你的要点来看它似乎是正确嵌套的,但实际上并非如此。哈姆尔非常清楚。 只是为了证明我的观点,就像haml中的上述形式一样:
= simple_form_for @contact do |f|
= f.input :name
= f.input :title
= f.input :company
= f.input :email
= f.input :notes
%h3 Goals
#goals
= f.simple_fields_for :goals do |goal|
= render 'goal_fields', :f => goal
.links
= link_to_add_association 'add goal', f, :goals
= f.submit
但我明白这是一个品味问题。
答案 1 :(得分:0)
在您的请求中,只有一个目标
"goals_attributes"=>{"0"=>{"title"=>"goal1", "due_date(1i)"=>"2014", "due_date(2i)"=>"5", "due_date(3i)"=>"11", "notes"=>"fdfsd", "_destroy"=>"false", "id"=>"13"}}}
我猜你在使用强参数做错了,把它改成这样的东西:
def contact_params
params.require(:contact)
.permit(:name, :title, :email, :company, :notes,
goal_attributes: [:title, :due_date, :notes, :_destroy, :id])
end