On 7/27/06, Jeremy Kemper <[EMAIL PROTECTED]> wrote:
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
Thanx Jeremy. This looks very different to what I had in mind. Lots better :)
I'll get into trying to get this to work.
Just a thought tho. By raising an exception, this would put destroy into a different category, this should perhaps be destroy! to fit with the other methods that raise errors.
Would including an exception into the destory method mean that it would break exisitng code? I guess you would only need to use a rescue if you have declared a relationship as rectricted. I'll have a go anyway and see what ppl think.
Thanx for you help
Cheers
_______________________________________________ Rails-core mailing list Rails-core@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails-core