Hi all, I am running into problems with my model relationships and destroying them. In particular: class Campaign < ActiveRecord::Base has_and_belongs_to_many :tags has_and_belongs_to_many :geographies end class Tag < ActiveRecord::Base has_and_belongs_to_many :campaigns end class Geographies < ActiveRecord::Base has_and_belongs_to_many :campaigns end class TagController < ApplicationController ... def destroy tag = Tag.find(:first, :conditions => ["id = ?",params[:id]]) tag.connection.delete("DELETE FROM campaigns_tags WHERE tag_id = '"+tag.id.to_s+"'") if tag.connection.execute("SELECT * FROM campaigns_tags WHERE tag_id = '"+tag.id.to_s+"'") tag.connection.delete("DELETE FROM spotprofile_taggings WHERE tag_id = '"+tag.id.to_s+"'") if tag.connection.execute("SELECT * FROM spotprofile_taggings WHERE tag_id = '"+tag.id.to_s+"'") tag.destroy redirect_to session[:back_page] end So, I have a symmetric habtm relationship between campaigns and tags, and campaigns and geographies. Why, when I attempt to "really" destroy the tag in the next to last line of the controller, do I get this stack trace? A SystemStackError occurred in tag#destroy: stack level too deep /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ associations/association_proxy.rb:123:in `load_target' . . . ------------------------------- Backtrace: ------------------------------- /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ associations/association_proxy.rb:123:in `load_target' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ associations/association_collection.rb:104:in `length' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ associations/association_collection.rb:64:in `clear' (eval):3:in `destroy_without_habtm_shim_for_geographies' (eval):4:in `destroy_without_habtm_shim_for_geographies' (eval):4:in `destroy_without_callbacks' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ callbacks.rb:332:in `destroy_without_transactions' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ transactions.rb:122:in `destroy' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ connection_adapters/abstract/database_statements.rb:51:in `transaction' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ transactions.rb:91:in `transaction' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ transactions.rb:118:in `transaction' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ transactions.rb:122:in `destroy' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ associations/association_proxy.rb:110:in `send' /usr/lib64/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/ associations/association_proxy.rb:110:in `method_missing' [RAILS_ROOT]/app/controllers/campaigns_controller.rb:193:in `destroy' /usr/lib64/ruby/gems/1.8/gems/actionpack-1.12.5/lib/ action_controller/base.rb:941:in `send' [the rest is mongrel and other stuff] The question is actually two-fold here: 1) How do I get into the campaigns destroy controller when I have already removed the links in the habtm table? For that matter, how am I getting there period... shouldn't the model's destroy method be the one called for cascading destroys? 2) Why am I running into stack overflow errors. Should there not be a symmetric habtm relationship there? If so how do I determine which table should habtm? Furthermore, this only happens sometimes when I destroy a campaign explicitly... sometimes the destroy works.
on 2007-03-06 15:50
on 2007-03-06 17:47
try has_many :through as an alternative... http://blog.hasmanythrough.com/2006/04/20/many-to-... 2007/3/6, Clever Neologism <firstname.lastname@example.org>:
on 2007-03-07 01:11
I'm curious about something. I swear everywhere I look habtm is being taken out to the shed. Why is that? habtm is a perfectly valid relation and yet it seems like everyone is always suggesting has_many :through like it's a fix all. has_many :through is a very clever habtm that appears only in situations where you have a class that has two belongs_to relationships to other classes that also wish to have a has_many relationship between them. I find myself with situations using habtm almost exclusively. I'm wondering if I'm just not doing a good job of modeling by not seeing this extra join model that should be appearing everywhere I have a habtm or is everyone else just looking for a way to use the new shiny object? So to help answer the original question, first off I'd ask why you're manually executing all that deletion SQL? If you want to delete a tag or campaign or whatever, just destroy it. Rails will delete the entry in the habtm join table for you automatically. If you need to delete a few of them and have it be atomic put the destroy calls in a transaction. Use the methods that AR gives you instead of managing it all yourself. You're fighting with it instead of letting it help you :-) Hope that helps, -Michael http://javathehutt.blogspot.com