3

I have 3 models in my project. User, Meal & Food. A user has many meals. A meal can have many food items and a food item can be a part of many meals. The user and the meal model are in a has_many association, while the meal and the food model are in a has_many :through association. The join model for the meal and the food model is called MealFood.

When deleting the user I have made it so that it deletes all of the meals that belong to the user. However I can't make it so that it also deletes all the associations of the meal that belong to the user.

I need to delete every record in the meal_foods table where the meal_id belongs to the user that is being deleted.

User Model

class User < ApplicationRecord
    has_many :meals, :dependent => :delete_all
end

Meal Model

class Meal < ApplicationRecord
    belongs_to :user, optional: true
    has_many :meal_foods, :dependent => :delete_all
    has_many :foods, through: :meal_foods
end

Food Model

class Food < ApplicationRecord
    has_many :meal_foods
    has_many :meals, through: :meal_foods
end

MealFood Model

class MealFood < ApplicationRecord
  belongs_to :meal
  belongs_to :food
end

Thanks in advance!

1 Answers1

2

You probably want dependent: :destroy, not dependent: :delete_all. :delete_all won't run callbacks and that's likely why your deeper associations remain persisted.

See the docs here:

For has_many, destroy and destroy_all will always call the destroy method of the record(s) being removed so that callbacks are run. However delete and delete_all will either do the deletion according to the strategy specified by the :dependent option, or if no :dependent option is given, then it will follow the default strategy. The default strategy is to do nothing (leave the foreign keys with the parent ids set), except for has_many :through, where the default strategy is delete_all (delete the join records, without running their callbacks).

This thread has better answers.

t56k
  • 6,769
  • 9
  • 52
  • 115
  • Do you mean `dependent: :destroy`, not `dependent :destroy_all`, because I get this error `syntax error, unexpected ':', expecting keyword_end has_many :meals, :dependent :destroy_all ` – Alexander Bogdanov Mar 06 '18 at 02:32
  • 1
    Thank you it worked! Since I'm using devise I had a problem when deleting it, but it turns out that it's because I'm using a join model that doesn't have an id column. Just saying if someone has the same issue, just add a primary key to your join table! – Alexander Bogdanov Mar 06 '18 at 02:48