Search code examples
validationruby-on-rails-4relationdestroy

Check Before Destroy or Destroy all Associated? Rails 4


I currently have a Vendor Model which acts as sort of a router for my users. This Vendor Model links up to locations that the vendor owns and campaigns as well.

Once a user is created, it is given a Vendor association which basically unlocks the locations and campaigns that pertain to that given Vendor.

Now, my question is, is there a way that when a Vendor is "Destroyed" that is can destroy all associated locations, campaigns and users linked to it? If not, is there a way to run a validation that if a Vendor is being destroyed to check the database for associations and not allow the action of destroy if it finds records?

The reason I ask is because if I destroy the Vendor, it leaves the users without locations and campaigns without an associated Vendor which basically crashes my application.

User Model

belongs_to :vendor #user can only have one vendor
has_many :locations, :through => :vendor
has_many :clients, :through => :vendor
has_many :campaigns, :through => :vendor  

Location Model

belongs_to :vendor
has_many :campaigns

Campaign Model

belongs_to :location
belongs_to :user
belongs_to :vendor
has_one :client

Vendor Model

has_many :locations #vendor can own many locations 
has_many :clients #vendor can have many clients. Allows multiple employees to see client list
has_many :campaigns #vendor can have many campaigns. Allows multiple employees to see campaigns

Solution

  • In short you can do something like this by using the dependent option on your assoication. Can use either:

    :destroy - destroys every associated object calling their destroy method.

    :delete_all - deletes every associated object without calling their destroy method.

    Update

    Taking your models into consideration you should do the following:

    class Vendor < ActiveRecord::Base 
    
      has_many :locations, dependent: :destroy
      has_many :clients, dependent: :destroy 
      has_many :campaigns, dependent: :destroy
    end 
    

    As stated above using the destroy option will destroy every associated object with that vendor.