ActiveRecord not destroying dependent records

Hi

I have a really simple and straight forward scenario.

A User model holds users. Each user can have several Feed Subscriptions.
I want the feed subscriptions to be destroyed alongside the user when
destroying a user.

The User model looks like this:

class User < ActiveRecord::Base
has_many :feed_subscriptions, :dependent => :destroy

end

but when destroying the user the feed subscriptions are still in the DB!
I have even added a before_destroy method to the FeedSubscription model
to get some feedback, but it is never called either…

Any ideas and suggestions are welcome!

Best regards
S

Well, how are you deleting the User records?

Other than that, is there anything in the log files about foreign key
reference violations?

Can’t surmise much more without more source code.

Jason

Ok… I’ll add some more source code too…

class FeedSubscription < ActiveRecord::Base
belongs_to :user
belongs_to :feed

def before_destroy
puts “Destroying subscription id #{id}”
end


end

class User < ActiveRecord::Base
has_many :feed_subscriptions, :dependent => :destroy

end

u = User.create(:password=>“E”, :password_confirmation=>“E”, :email=>“E”)
=> #<User:0x33f4fb4 @new_record=false, @new_record_before_save=true,
@password=“E”, @attributes={“word_occurrences_count”=>0,
“salt”=>“272404100.524279319982906”, “name”=>nil, “look_for_words”=>[],
“hashed_password”=>“0056fef0f0b99b94644a138ee75bdcc60aa9ddcd”, “id”=>21,
“authors”=>{}, “time_zone”=>0, “prefs”=>{}, “email”=>“E”},
@errors=#<ActiveRecord::Errors:0x33f3e34 @errors={},
@base=#<User:0x33f4fb4 …>>, @password_confirmation=“E”>

FeedSubscription.count
=> 0

u.feed_subscriptions.create
=> #<FeedSubscription:0x33e8764 @new_record=false,
@attributes={“voted_positive”=>0, “standard_rating”=>0,
“posts_blocked”=>0, “id”=>18, “posts_served”=>0, “feed_id”=>nil,
“voted_negative”=>0, “user_id”=>21},
@errors=#<ActiveRecord::Errors:0x33e7cec @errors={},
@base=#<FeedSubscription:0x33e8764 …>>>

FeedSubscription.count
=> 1

u.destroy
=> #<User:0x33f4fb4 @feed_subscriptions=[#<FeedSubscription:0x33de548
@attributes={“voted_positive”=>“0”, “standard_rating”=>“0”,
“posts_blocked”=>“0”, “posts_served”=>“0”, “id”=>“18”, “feed_id”=>nil,
“voted_negative”=>“0”, “user_id”=>“21”}>], @feed_user_entries=[],
@new_record=false, @word_occurrences=[], @new_record_before_save=true,
@password=“E”, @attributes={“word_occurrences_count”=>0,
“salt”=>“272404100.524279319982906”, “name”=>nil, “look_for_words”=>[],
“hashed_password”=>“0056fef0f0b99b94644a138ee75bdcc60aa9ddcd”, “id”=>21,
“authors”=>{}, “time_zone”=>0, “prefs”=>{}, “email”=>“E”},
@errors=#<ActiveRecord::Errors:0x33f3e34 @errors={},
@base=#<User:0x33f4fb4 …>>, @password_confirmation=“E”>

FeedSubscription.count
=> 0

Everything looks ok there in the log above but the damn callback
function in FeedSubscription never gets called! The mongrel log that
normally would log stuff like that to doesn’t mention it either:

SQL (0.000532) INSERT INTO users (name, salt,
word_occurrences_count, look_for_words, hashed_password,
authors, time_zone, prefs, email) VALUES(NULL,
‘272404100.524279319982906’, 0, ‘— []\n\n’,
‘0056fef0f0b99b94644a138ee75bdcc60aa9ddcd’, ‘— {}\n\n’, 0, ‘—
{}\n\n’, ‘E’)
SQL (0.010676) COMMIT
SQL (0.000552) SELECT count() AS count_all FROM feed_subscriptions
SQL (0.000258) BEGIN
SQL (0.000386) INSERT INTO feed_subscriptions (voted_positive,
standard_rating, posts_blocked, posts_served, feed_id,
user_id, voted_negative) VALUES(0, 0, 0, 0, NULL, 21, 0)
SQL (0.009999) COMMIT
SQL (0.000556) SELECT count(
) AS count_all FROM feed_subscriptions
SQL (0.000262) BEGIN
FeedSubscription Load (0.001010) SELECT * FROM feed_subscriptions
WHERE (feed_subscriptions.user_id = 21)
FeedSubscription Destroy (0.000391) DELETE FROM feed_subscriptions
WHERE id = 18

FeedUserEntry Load (0.000998) SELECT * FROM feed_user_entries WHERE
(feed_user_entries.user_id = 21)
WordOccurrence Load (0.000700) SELECT * FROM word_occurrences WHERE
(word_occurrences.user_id = 21)
User Destroy (0.000348) DELETE FROM users
WHERE id = 21

SQL (0.010046) COMMIT
SQL (0.000537) SELECT count(*) AS count_all FROM feed_subscriptions

Jason R. wrote:

Well, how are you deleting the User records?

Other than that, is there anything in the log files about foreign key
reference violations?

Can’t surmise much more without more source code.

Jason

I am deleting them using u.destroy where is the user to destroy.
Now it sort of works though… Really don’t get this… Now it actually
destroys the subscriptions…
But it still doesn’t call the before_destroy method I have added in the
FeedSubscription model… and no hint in the log either…

I believe the reason it is not calling before_destroy on the dependent
records is because it does a mass delete of all the subscriptions
which is much much much faster than loading each of the records in
order to call it’s before_destroy hook.

I tihnk the workaround you came up with is the best compromise of
architecture and performance.

On May 22, 8:06 am, Sebastian probst Eide <rails-mailing-l…@andreas-

I believe the reason it is not calling before_destroy on the dependent
records is because it does a mass delete of all the subscriptions
which is much much much faster than loading each of the records in
order to call it’s before_destroy hook.
Yes, I guess that has to be the reason! Thanks for your time though!

Best regards
Sebastian

Well… I found a solution. Not a very beautiful one though…
The before_destroy method of the user model is called so in that method
I call a function in the feed_subscription model doing the work I would
normally have done in the FeedSubscriptions before_destroy model…

Sort of works now!

Sebastian probst Eide wrote:

I believe the reason it is not calling before_destroy on the dependent
records is because it does a mass delete of all the subscriptions
which is much much much faster than loading each of the records in
order to call it’s before_destroy hook.
Yes, I guess that has to be the reason! Thanks for your time though!

Best regards
Sebastian

Hey you might also try just adding a foreign key relationship and let
the database do the work. If you always want to delete the subscriptions
when the user is destroyed.

Add to a migration file for mysql:

ActiveRecord::Migration.execute(“ALTER TABLE feed_subscriptions ADD
CONSTRAINT fk_feed_subscriptions_users FOREIGN KEY (user_id)
REFERENCES users (id) ON DELETE CASCADE”)

Hey you might also try just adding a foreign key relationship and let
the database do the work. If you always want to delete the subscriptions
when the user is destroyed.
Well, I guess that would normally make a lot of sense, but not in my
case. I have to do a lot of housekeeping and check different things
before actually deleting the records.

But thanks for the suggestion!

S

On Tue, 22 May 2007 15:29:26 +0200, Sebastian probst Eide wrote:

class User < ActiveRecord::Base
has_many :feed_subscriptions, :dependent => :destroy …
end
[…]

You’re not using Feed-on-Feeds, are you?

-Thufir

You’re not using Feed-on-Feeds, are you?
-Thufir

Hi Thufir
No I am not.
What is Feed-on-feeds?

Best regards
Sebastian

On Jun 17, 12:19 pm, Sebastian probst Eide <rails-mailing-l…@andreas-
s.net> wrote:

You’re not using Feed-on-Feeds, are you?
-Thufir

Hi Thufir
No I am not.
What is Feed-on-feeds?
[…]

http://code.google.com/p/feed-on-feeds/

it’s an rss aggregator which persists the data to MySQL. It ueses PHP
and the database schema is, unfortunately, anti-RoR. Otherwise, it’s
a very neat RSS agregator. Are you doing RSS aggregation, or did I
misunderstand?

-Thufir

On Jun 17, 11:26 pm, Sebastian probst Eide <rails-mailing-l…@andreas-
s.net> wrote:

aggregator myself though in ruby and I am using a parser called
SimpleRSS

This is for personal use? work? commercial? open source?

-Thufir

Well… sort of none of the above… it is sort of a mix between
commercial and for personal use, but mainly meant to be non profit. It
is not open source though…

You can find the site at http://kle.io/. I am going to reinstall the
server soon because something is terribly wrong and the site is
incredibly slow as it is right now.

Kle.io is a RSS-filter. You give give it the feeds you normally
subscribe to and it gives you one or multiple output feeds. While
reading the posts you tell it which ones you like and which ones you
don’t and then it adapts to your reading habits and starts filtering out
the posts it anticipates you wouldn’t like to read anyway. It is sort of
a secretary sorting through your mail (in this case RSS feeds) and just
letting through the ones that are worthy your attention.

It worked pretty well in a alpha mode on my local development station,
but I am in the process of rewriting the whole system to make it faster
and not as memory hungry.

Sebastian

http://code.google.com/p/feed-on-feeds/

it’s an rss aggregator which persists the data to MySQL. It ueses PHP
and the database schema is, unfortunately, anti-RoR. Otherwise, it’s
a very neat RSS agregator. Are you doing RSS aggregation, or did I
misunderstand?

-Thufir

No, you didn’t misunderstand. I am doing RSS aggregation. I wrote the
aggregator myself though in ruby and I am using a parser called
SimpleRSS

Sebastian