user5527042
user5527042

Reputation:

Can't Delete Records In Ruby on Rails

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

Answers (2)

Semjon
Semjon

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

Jon
Jon

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

Related Questions