controlling join table actions based on join table content

Tony
2009-09-11T20:38:20Z

I have an active record association that when I delete the parent
object the ::dependent => :nullify  option works correctly and sets
the FKs to nil in the join table.  Is there a way to make this happen
when the record is updated too?   When I remove an association from
the parent, the association is deleted instead of setting the FK to
nil.

To complicate things there are times when I would like the behavior to
be :dependent => :destroy_all (depending on what is in the join
table).

I am using has_many :through and depending on what is in my join table
I may want to destroy instead of nullify.

Is this a job for an observer on the join table or maybe overriding
the destroy method :-\

Fabricated Example (i need a better example)
-----------------------------

Lets say there is a company that manages shooting locations for
movies.  The company offers 2 types of contracts (transferable and
fixed).

class Movie < ActiveRecord::Base
  has_many :contracts, :dependent => :nullify
  has_many :locations, :through => :contracts
end
class Contract < ActiveRecord::Base
  belongs_to :location    # location_id is unique.
  belongs_to :movie
# There is a contract type.  fixed or transferable
# transferrable contracts can have a nil movie.  A fixed one can not
end
class Location < ActiveRecord::Base
  has_many :contracts
  has_many :movies, :through => :contracts
end

A movie may purchase several locations (contracts).  If the movie is
canceled, the locations are freed up (if using  :dependent
=> :destroy_all),  If any locations are changed the unreferenced
locations are deleted.  This all works fine.

But what if I have a contract that allows me to transfer a location I
purchased to another movie.  If my contract_type is transferable and I
delete the movie the contract should remain but not reference any
movie until I reassign it (dependent => :nullify).   The contract
should also remain if I remove just 1 location from my movie and I
want to transfer it to another movie at a later point.