Created
August 11, 2011 18:20
-
-
Save jfeust/1140340 to your computer and use it in GitHub Desktop.
Rails Association Id Cleanup On Destroy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# I found a bit of odd rails behavior recently. Consider the following classes. | |
class Contact < ActiveRecord::Base | |
belongs_to :gallery | |
end | |
class Gallery < ActiveRecord::Base | |
has_many :contacts | |
end | |
# All is well and good. But let's say I have a Gallery and a Contact associated with it. | |
g = Gallery.first # id = 1 | |
c = g.contacts.first | |
c.gallery_id # => 1 | |
# So now we destroyed the gallery, but we still want the contact to stick around, which | |
# it does. We would assume the relationship is also gone from the contact to the gallery | |
# which it is. | |
g.destroy | |
c.gallery # => nil | |
# However, the gallery_id value on the contact remains 1 even though we no longer have | |
# a gallery with id = 1. | |
c.gallery_id # => 1 | |
# This is fine by rails as it's smart enough to handle this, but what about if we want | |
# to do checks using gallery_id. | |
# For example if you have the contact in memory and only want to check the existence | |
# of gallery association you can do that by checking gallery_id and thus you don't have | |
# to make another call to the DB. This rails functionality of keeping the gallery_id | |
# even when the gallery doesn't exist however makes this check faulty. | |
# The Fix | |
class Gallery < ActiveRecord::Base | |
has_many :contacts | |
before_destroy { |gallery| gallery.contacts.clear } | |
end | |
# Adding this before_destroy tells rails to clear all the gallery contacts associations | |
# (and associated id's) before we remove the gallery. Now you have nice clean association | |
# ids that actually match your association existence. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment