Re: controlling join table actions based on join table content

Tony Primerano
2009-09-11T23:02:45Z

overriding the Movie destroy method works fine for killing
''fixed''
contracts before ActiveRecord makes them null.

At 1st I was thinking of catching the nullify via a callback on the
Contract class (wasn''t sure what I was going to do here but it appears
the nullification doesn''t invoke the callbacks).

Next up.  prevent location update on a movie object from deleting
transferable contracts.  I guess I''ll need to make locations
attr_protected and manually make updates to the contracts.



On Sep 11, 4:38 pm, Tony
<tony.primer...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:
> 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.