LondonGuy
LondonGuy

Reputation: 11098

How do I correctly destroy associated records in ruby on rails?

I have a method that virtually deletes ALL messages of a current_user and by virtually I mean it just sets the status for all there messages in the message table to 1 which means the message won't show to the user who deletes the messages.

message_thread belongs to message message has one message_thread

Here is my model method that takes care of this:

    def delete_all_users_messages(user_id, parent_id)
      message = Message.find_by_parent_id(parent_id)
      message.children.where( :sender_id => user_id ).update_all( :sender_status => 1)
      message.children.where( :recipient_id => user_id ).update_all( :recipient_status => 1 )
      thread = message.message_thread
      thread.update_attribute(:sender_status, 1) if thread.sender_id == user_id 
      thread.update_attribute(:recipient_status, 1) if thread.recipient_id == user_id 
      if thread.sender_status == 1 && thread.recipient_status == 1
      thread.destroy
      Message.destroy_all(:parent_id => parent_id)
      end
    end

I have a message_threads table that references messages in my messages table. it references the first message of a conversation who's parent_id is equal to the id of the message which means. This first message has children.

As you can see at the end of my method I destroy the thread in the message_threads table if both users status's in that table are set to 1 then delete any messages left.

I tested this with 1 users account and it worked for updating the users message_thread status to 1 and all that users messages.

So I went to the account of the user they were in conversation with and tried the same thing and I get:

When I check the records the messages status's for this user do get set to. The message thread is deleted.

But the messages are still in the message table and I get:

stack level too deep

Here is the controller action:

  def destroy_all_messages
    Message.delete_all_users_messages(current_user.id, params[:format])
    flash[:success] = "Messages deleted"
    redirect_to messages_path
  end

Looks like a continuous loop in my logs. Is this what could be causing the issue? I deleted some because it wouldn't all fit but I'm sure you can see the repeating going on in the logs.

Started DELETE "/messages/delete_all_messages.315" for 127.0.0.1 at 2012-02-21 15:27:14 +0000
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1] Processing by MessagesController#destroy_all_messages as 
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   Parameters: {"authenticity_token"=>"yelkcp72223dji4YVumgG9gUEK/U/Mwqwd0pc1WRG+0="}
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 4 LIMIT 1
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   Message Load (0.9ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315 LIMIT 1
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   SQL (20.8ms)  UPDATE `messages` SET `sender_status` = 1 WHERE `messages`.`parent_id` = 315 AND `messages`.`sender_id` = 4
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   SQL (37.3ms)  UPDATE `messages` SET `recipient_status` = 1 WHERE `messages`.`parent_id` = 315 AND `messages`.`recipient_id` = 4
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   MessageThread Load (0.4ms)  SELECT `message_threads`.* FROM `message_threads` WHERE `message_threads`.`message_id` = 315 ORDER BY message_threads.updated_at DESC LIMIT 1
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]    (0.1ms)  BEGIN
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]    (0.3ms)  UPDATE `message_threads` SET `recipient_status` = 1, `updated_at` = '2012-02-21 15:27:14' WHERE `message_threads`.`id` = 803
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]    (0.4ms)  COMMIT
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]    (0.1ms)  BEGIN
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   SQL (0.2ms)  DELETE FROM `message_threads` WHERE `message_threads`.`id` = 803
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]    (0.3ms)  COMMIT
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   Message Load (0.3ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]    (0.1ms)  BEGIN
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM 
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]   CACHE (0.0ms)  SELECT `messages`.* FROM `messages` WHERE `messages`.`parent_id` = 315
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1]    (0.1ms)  ROLLBACK
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1] Completed 500 Internal Server Error in 400ms
[51b1090d2a7185c9b2f42fa3213006d1] [127.0.0.1] 
SystemStackError (stack level too deep):
  actionpack (3.2.0) lib/action_dispatch/middleware/reloader.rb:70

Kind regards

Upvotes: 1

Views: 768

Answers (1)

Xavier Holt
Xavier Holt

Reputation: 14621

I suspect the loop is being caused by the destroy methods. I can't see exactly how from the code you've posted, but look for either of the following: Custom destroy or before_destroy methods that you've written that call the destroy method on other objects, or relations with a :dependent => :destroy[_all] modifier. If either of those things manage to create a cyclic dependency, you're stuck in a loop.

Also: If you have a model where the destroy method doesn't need to do anything, use delete and delete_all for that model instead. These don't run any destructors - they just delete rows straight from the DB - so they're faster, and you don't risk looping. Of course, you can't do this when a model is expected to clean up it's children, but for "leaf" models, they're great.

Hope this helps!

Upvotes: 2

Related Questions