Forum: Ruby on Rails habtm recursion via destroy_without_callbacks

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C5adc4718cf44543d02a76df853f99cc?d=identicon&s=25 Eric Soderberg (soderic)
on 2005-12-31 17:45
I am having a problem with two models that each have a HABTM
relationship to the other. For example:

CREATE TABLE people (id INT, name TEXT);
CREATE TABLE teams (id INT, name TEXT);
CREATE TABLE people_teams (person_id INT, team_id INT);

The person model has:

has_and_belongs_to_many :teams

And the team model has:

has_and_belongs_to_many :people

The trouble comes when trying to destroy something, I end up with a
recursive stack sequence that looks something like:

(eval):7:in `destroy_without_habtm_shim_for_teams'
(eval):9:in `destroy_without_habtm_shim_for_teams'
(eval):9:in `destroy_without_callbacks'
...

This appears to be due to something in associations.rb where the
association array is cleared as part of destroying the record. What
appears to be happening is that when person.rb is loaded, its HABTM
causes team.rb to be loaded which ends up reloading person.rb? I've
added some instrumentation that shows that the
destroy_without_habtm_shim_for_teams method ends up being added twice.
This causes recursion when the record is destroyed. I've worked around
this by embedding this method aliasing inside an "unless
method_defined?()" to prevent the recursive situation. However, I'm
suspecting that I'm missing something else obvious.

I am using activerecord 1.13.2 and rails 1.0.0.
51f10739fd903d3b57561a15e4598954?d=identicon&s=25 M Daggett (Guest)
on 2006-01-02 01:33
(Received via mailing list)
I am having the same problem. I think that it has something to do with
mysql. As of yet, I have no solutions for the problem.


On 12/31/05, Eric Soderberg <soderic@earthlink.net> wrote:
>
> ...
> suspecting that I'm missing something else obvious.
>
> I am using activerecord 1.13.2 and rails 1.0.0.
>
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>


--
51f10739fd903d3b57561a15e4598954?d=identicon&s=25 M Daggett (Guest)
on 2006-01-02 23:45
(Received via mailing list)
There is also a post about this on railsweenie
http://rails.techno-weenie.net/question/2005/12/23...

On 1/1/06, M Daggett <heavysixer@gmail.com> wrote:
> > CREATE TABLE people_teams (person_id INT, team_id INT);
> > recursive stack sequence that looks something like:
> > added some instrumentation that shows that the
> > _______________________________________________
> > Rails mailing list
> > Rails@lists.rubyonrails.org
> > http://lists.rubyonrails.org/mailman/listinfo/rails
> >
>
>
> --
> --------------------------------------------------------------------
> I am Mark Daggett and I approve this message.
>


--
4a4d97879b09aca01f3036055ef4813a?d=identicon&s=25 Brian Green (Guest)
on 2006-01-03 04:21
(Received via mailing list)
Hi Eric, I'm running into the same problem. Could you provide a little
more
detail on your workaround? Thanks,

Brian
C5adc4718cf44543d02a76df853f99cc?d=identicon&s=25 Eric Soderberg (soderic)
on 2006-01-03 05:53
Brian,

I changed the implementation of has_and_belongs_to_many() in
associations.rb
(gems/1.8/gems/activerecord-1.13.2/lib/active_record/associations.rb) to
check for the existence of the shim method:

        # Don't use a before_destroy callback since users'
before_destroy
        # callbacks will be executed after the association is wiped out.
        old_method =
"destroy_without_habtm_shim_for_#{association_name}"
        unless method_defined?(old_method) # !!!
          class_eval <<-end_eval
            alias_method :#{old_method}, :destroy_without_callbacks
            def destroy_without_callbacks
              #{association_name}.clear
              #{old_method}
            end
          end_eval
        end # !!!

I added the two lines with '# !!!'.

This feels more like a band-aid than a fix since I would expect this
has_and_belongs_to_many call to not occur twice to begin with. Just
haven't had time track it down further yet.

Eric

Brian Green wrote:
> Hi Eric, I'm running into the same problem. Could you provide a little
> more
> detail on your workaround? Thanks,
>
> Brian
4a4d97879b09aca01f3036055ef4813a?d=identicon&s=25 Brian Green (Guest)
on 2006-01-03 06:55
(Received via mailing list)
Thanks, Eric, I'll try this out. (Band-aid, perhaps, but if it works...)

Looks like this: http://dev.rubyonrails.org/ticket/3175 might be the
same
issue?

Brian
0b8546bfb0772d6aad91cafb4255ca7f?d=identicon&s=25 Bryan Corey (Guest)
on 2006-05-24 18:27
(Received via mailing list)
> >
> > The trouble comes when trying to destroy something, I end up with a
> > recursive stack sequence that looks something like:
> >
> > (eval):7:in `destroy_without_habtm_shim_for_teams'
> > (eval):9:in `destroy_without_habtm_shim_for_teams'
> > (eval):9:in `destroy_without_callbacks'
> > ...

> >
> > I am using activerecord 1.13.2 and rails 1.0.0.


The problem is rails 1.0. It's been documented in a bug ticket. Upgrade
to 1.1.2
to fix the issue.

I got my issue fixed yet now I still can't do destroy via unit or
functional
tests without getting the same issue again.
This topic is locked and can not be replied to.