Eric Soderberg
2005-Dec-31 16:45 UTC
[Rails] habtm recursion via destroy_without_callbacks
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. -- Posted via http://www.ruby-forum.com/.
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:> 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. > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- -------------------------------------------------------------------- I am Mark Daggett and I approve this message.
There is also a post about this on railsweenie http://rails.techno-weenie.net/question/2005/12/23/how_to_destroy_from_model_unit_tests_for_has_and_belongs_to_many On 1/1/06, M Daggett <heavysixer@gmail.com> wrote:> 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: > > 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. > > > > -- > > Posted via http://www.ruby-forum.com/. > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > -- > -------------------------------------------------------------------- > I am Mark Daggett and I approve this message. >-- -------------------------------------------------------------------- I am Mark Daggett and I approve this message.
Hi Eric, I''m running into the same problem. Could you provide a little more detail on your workaround? Thanks, Brian On 12/31/05, Eric Soderberg <soderic@earthlink.net> wrote:> > 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. > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060103/e5589268/attachment.html
Eric Soderberg
2006-Jan-03 04:53 UTC
[Rails] Re: habtm recursion via destroy_without_callbacks
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-- Posted via http://www.ruby-forum.com/.
Brian Green
2006-Jan-03 05:55 UTC
[Rails] Re: habtm recursion via destroy_without_callbacks
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 On 1/2/06, Eric Soderberg <soderic@earthlink.net> wrote:> > 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 > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060103/86e936b6/attachment-0001.html
Bryan Corey
2006-May-24 16:25 UTC
[Rails] Re: habtm recursion via destroy_without_callbacks
> > > > 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.