Reputation: 6805
I'm banging my head trying to figure this one out. I have the following form, which works great!
<%= bootstrap_form_for @template do |f| %>
<%= f.text_field :prompt, :class => :span6, :placeholder => "Which one is running?", :autocomplete => :off %>
<%= f.select 'group_id', options_from_collection_for_select(@groups, 'id', 'name') %>
<% 4.times do |num| %>
<%= f.fields_for :template_assignments do |builder| %>
<%= builder.hidden_field :choice_id %>
<%= builder.check_box :correct %>
<% end %>
<% end %>
<% end %>
Then I have my model:
class Template < ActiveRecord::Base
belongs_to :group
has_many :template_assignments
has_many :choices, :through => :template_assignments
accepts_nested_attributes_for :template_assignments, :reject_if => lambda { |a| a[:choice_id].blank? }, allow_destroy: true
end
When the form is submitted, the nested attributes are added beautifully. However, when I want to delete a Template, I also want it to delete all the children "template_assignments" as well, which is what I assumed "allow_destroy => true"
So, I am trying this from the Rails Console (which could be my issue??) I'll do something like:
>> t = Template.find(1)
#Which then finds the correct template, and I can even type:
>> t.template_assignments
#Which then displays the nested attributes no problem, but then I try:
>> t.destroy
#And it only destroys the main parent, and none of those nested columns in the TemplateAssignment Model.
Any ideas what I am doing wrong here? Is it because you can't do it in the Rails Console? Do I need to do it in a form instead? If so, how do I achieve this in a form?
Any help would be great!
Upvotes: 2
Views: 5821
Reputation: 26193
Specify that child template_assignments
should be destroyed upon the destruction of the parent Template
:
# app/models/template.rb
has_many :template_assignments, dependent: :destroy
The following depicts the steps that Rails takes to destroy an object's dependent associations:
# from the Rails console
>> t = Template.find(1)
#=> #<Template id:1>
>> t.template_assignments.first
#=> #<TemplateAssignment id:1>
>> t.destroy
#=> SELECT "template_assignments".* FROM "template_assignments" WHERE "template_assignments"."template_id" = 1
#=> DELETE FROM "template_assignments" WHERE "template_assignments"."id" = ? [["id", 1]]
>> TemplateAssignment.find(1)
#=> ActiveRecord::RecordNotFound: Couldn't find TemplateAssignment with id=1
The :dependent
option can be specified on either side of the association, so it can alternatively be declared on the child association, rather than the parent:
# app/models/template_assignment.rb
belongs_to :template, dependent: :destroy
From the Rails docs:
has_many, has_one and belongs_to associations support the :dependent option. This allows you to specify that associated records should be deleted when the owner is deleted
Upvotes: 6