On Jul 26, 2006, at 6:06 AM, Daniel N wrote:
I've had a crack at this one and it is as I feared.

If I define the restrict association first, then the destroy chain is halted and all is well. But if I have an association where a :dependent => :destroy is declared before the association with :restrict then the first association is destroyed before the destroy chain is halted.

You can wrap the destroy method to leapfrog the callback chain.

associations.rb, configure_dependency_*

  case reflection.options[:dependent]
    when :restrict
      class_eval <<-end_eval
        def destroy_with_has_many_#{reflection.name}
          unless #{reflection.name}.blank?
raise DestroyRestricted.new(self, # {reflection.name.inspect})
          end
        end

        alias_method_chain :destroy, "has_many_#{reflection.name}"
      end_eval
    # ...
  end


base.rb

  module ActiveRecord
    class DestroyRestricted < ActiveRecordError
      def initialize(model, by)
super "#{model.class.name} #{model.id} destroy restricted by #{by}"
      end
    end
  end


I have taken my first real plunge into the rails source and found a number of places where I thought a transaction might go to prevent this but to no avail. Actually my head is spinning a bit trying to put all the pieces of active_record together.

For this to work I think I need to put a transaction around the entire destroy chain, but I have no idea how to do this.

Any pointers anyone could give would be great.

destroy and its callbacks are wrapped in a single transaction (see transactions.rb) so you can raise an exception to rollback.


example:

  class ParentController < ApplicationController
    def destroy
      @parent.destroy
      redirect_to parent_url(@parent)
    rescue ActiveRecord::DestroyRestricted => restricted
      flash[:error] = restricted.message
      redirect_to :back
    end
  end


Best,
jeremy
_______________________________________________
Rails-core mailing list
Rails-core@lists.rubyonrails.org
http://lists.rubyonrails.org/mailman/listinfo/rails-core

Reply via email to