如何正确销毁 ruby on rails 中的关联记录?
Posted
技术标签:
【中文标题】如何正确销毁 ruby on rails 中的关联记录?【英文标题】:How do I correctly destroy associated records in ruby on rails? 【发布时间】:2012-02-21 17:32:20 【问题描述】:我有一种方法可以虚拟删除 current_user 的所有消息,实际上我的意思是它只是将消息表中所有消息的状态设置为 1,这意味着该消息不会显示给删除消息的用户.
message_thread 属于消息 message 有一个 message_thread
这是我的模型方法来处理这个问题:
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
我有一个 message_threads 表,它引用了我的消息表中的消息。它引用了会话的第一条消息,其 parent_id 等于消息的 id,这意味着。第一条消息有子级。
正如您在我的方法末尾看到的那样,如果该表中的两个用户状态都设置为 1,我会销毁 message_threads 表中的线程,然后删除剩余的所有消息。
我用 1 个用户帐户对此进行了测试,它可以将用户 message_thread 状态更新为 1 以及所有用户消息。
所以我去了他们正在交谈的用户的帐户并尝试了同样的事情,我得到:
当我检查记录时,该用户的消息状态确实被设置为。消息线程被删除。
但消息仍在消息表中,我得到:
堆栈级别太深
这是控制器动作:
def destroy_all_messages
Message.delete_all_users_messages(current_user.id, params[:format])
flash[:success] = "Messages deleted"
redirect_to messages_path
end
在我的日志中看起来像是一个连续循环。这是导致问题的原因吗?我删除了一些,因为它不完全适合,但我相信您可以在日志中看到重复发生的情况。
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
亲切的问候
【问题讨论】:
【参考方案1】:我怀疑循环是由destroy
方法引起的。我无法从您发布的代码中看到确切的方式,但请查找以下任一内容:您编写的自定义 destroy
或 before_destroy
方法在其他对象或关系上调用 destroy
方法带有:dependent => :destroy[_all]
修饰符。如果这些事情中的任何一个设法创建了循环依赖项,那么您就会陷入循环。
另外:如果您有一个模型,其中 destroy
方法不需要做任何事情,请使用 delete
和 delete_all
代替该模型。它们不运行任何析构函数——它们只是直接从数据库中删除行——所以它们更快,而且你不会冒险循环。当然,当一个模型需要清理它的孩子时,你不能这样做,但是对于“叶子”模型,它们很棒。
希望这会有所帮助!
【讨论】:
即使只是运行这个“Message.destroy_all(:parent_id => 315) 也会在 Rails 控制台中给我循环然后堆栈级别太深的错误。我猜这与孩子们有关。 @LondonGuy - 似乎很可能。你能把它改成delete_all
电话吗?如果消息没有他们自己需要删除的任何子级,那应该可以解决它。
好吧,我想我明白了。这是因为所有子节点的第一个父节点的 parent_id 设置为消息的 primary_id。但早些时候在我的项目中的其他地方,我将它设置为这样,以便当我调用“孩子”时,我可以调用所有消息。如果第一个没有设置,那么当我打电话给孩子时它就会被忽略。因此,我应该使用 sender_id 和 recipient_id 而不是通过 parent_id 查找消息。仅使用 parent_id 更容易找到,但我想如果找不到解决方案,我将不得不以另一种方式进行
Delete_all 适用于所有 parent_id 的集合,甚至是实际的父母 parent_id 集合。嗯,想知道delete_all和destroy_all有什么大区别
@LondonGuy - '害怕你把我弄丢了,但很高兴听到它正在工作!无论如何,this 是我发现的关于删除和销毁之间差异的最佳解释。仍然不是很清楚,但希望仍然有用。干杯!以上是关于如何正确销毁 ruby on rails 中的关联记录?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Ruby on Rails 中“漂亮”地格式化 JSON 输出
如何使用 json 文件在 ruby on rails 中填充模型(数据库)?
如何在 ruby on rails 中访问 rails 助手和嵌入资产 javascript 文件中的 ruby?