Reputation:
I have three models. Customer, Job, and Receipt.
Customer has many Jobs and Jobs has many Receipts. Job belongs to Customer and Receipts belongs to Job.
In my delete def for my customer, I want to delete all of the customers jobs and the job receipts. Here is my controller code
def destroy
customer = Customer.find(params[:id])
customer.jobs.receipts.destroy_all #this line crashes
customer.jobs.destroy_all
customer.destroy
redirect_to customers_url
redirect_to show_todays_jobs_path
end
The line that says customer.jobs.receipts.destroy_all throws an error that states that the receipts method is undefined.
However, in my Jobs controller, jobs.receipts.destroy_all works just fine. In the customer controller if I remove the line to destroy receipts then that works fine too.
I don't understand why it I can't delete the receipts in the Customer controller. Please help me out here. Thanks in advance
Upvotes: 0
Views: 2228
Reputation: 1023
Problem in your code that customer.jobs
is a collection where each job record has its own collection of receipts. You may use association has_many :receipts, through: :jobs
in the Customer model to obtain direct customer.receipts
reference, then you can call customer.receipts.delete_all
. Documentation here.
Seems you could use dependent: :destroy
or dependent: :delete_all
for your associations has_many
, briefly it will delete associations when the customer
object is destroyed. Checkout the documentation.
Take a look on code example:
class Customer
has_many :jobs, dependent: :destroy
end
class Job
has_many :receipts, dependent: :destroy
end
Then when you call customer.destroy
all related jobs and receipts could be destroyed as well.
PS. You have another mistake in controller code - redirect_to
called twice, only one time is possible.
Upvotes: 1
Reputation: 10898
You shouldn't be doing these deletes yourself manually in your controller. There are parameters you can provide to your associations in your models to tell them to destroy the associated records when destroying the parent.
I've made some assumptions about your model associations, but something along the lines of the following should work for you:
class Customer < ActiveRecord::Base
has_many :jobs, dependent: :destroy
end
class Job < ActiveRecord::Base
belongs_to :customer
has_many :receipts, dependent: :destroy
end
class Receipt < ActiveRecord::Base
belongs_to :job
end
Setting dependent: :destroy
on the association tells rails to delete the associated records by calling their destroy
method when deleting the parent object.
With this set up, you can just do this in your destroy
action within your controller (note there's no need to find
your record before you destroy
it):
def destroy
Customer.destroy(params[:id])
redirect_to customers_url
end
Upvotes: 0