Don't forget: Automatically remove join records on has_many :through associations

Updated . Posted . Visible to the public. Repeats.

Bad

# Given the following models

class Image < ActiveRecord::Base
  has_many :album_images
  has_many :albums, through: :album_images
end

class Album < ActiveRecord::Base
  has_many :album_images
  has_many :images, through: :album_images
end

# Join model
class AlbumImage < ActiveRecord::Base
  belongs_to :album
  belongs_to :image
end

Destroying a record in this setup will only remove the record itself, and leave orphaned join records behind.

image = Image.last
image.destroy # removes only the `image` record,
              # but none of the associated `album_image` join records

Good

By adding the :dependent => :destroy option to the has_many :through associations, the join records will be removed when an image or an album is destroyed.

class Image < ActiveRecord::Base
  has_many :album_images
  has_many :albums, through: :album_images, dependent: :destroy
end

class Album < ActiveRecord::Base
  has_many :album_images
  has_many :images, through: :album_images, dependent: :destroy
end

Note: the associated record with through (the albums in the example) will never be deleted by specifying dependent: :destroy, only the join records. Thus the following example will have the same effect as the above and is more explicit:

class Image < ActiveRecord::Base
  has_many :album_images, dependent: :destroy
  has_many :albums, through: :album_images
end
Last edit
Michael Leimstädtner
License
Source code in this card is licensed under the MIT License.
Posted to makandra dev (2015-04-17 12:18)