除了ruby on rails之外,我将如何destroy_all或delete_all记录?

时间:2012-02-22 00:04:11

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1 rubygems

我在我的网站上为我的用户消息传递线程功能使用“acts_as_tree”插件。我有一个方法可以删除选定的消息。消息实际上不会被删除。其sender_status或recipient_status列设置为1,具体取决于用户是邮件的发件人或收件人。

无论如何,如果两个用户都将这些状态设置为1,则最后一行确保消息行完全从数据库移出。现在这很好,只要它不是父信息被删除。如果父邮件已删除,则将无法再访问尚未选择删除的子邮件。

以下是方法:

        def delete_all_users_selected_messages(message_ids, user_id, parent_id)
          Message.where(:id => message_ids, :sender_id => user_id).update_all(:sender_status => 1)
          Message.where(:id => message_ids, :recipient_id => user_id).update_all(:recipient_status => 1)
          Message.delete_all(:sender_status => 1, :recipient_status => 1, :parent_id => parent_id).where("id != ?", parent_id)
        end

我正在努力做的很明显。我需要忽略父级。因此,主键等于parent_id意味着该行是父(通常,parent_id是nil,但我需要将其设置为主键值,因为其他原因,长篇故事并不重要)。无论如何是否有一个SQL语句我可以添加到tat方法的最后一行的末尾?确保它只删除行的id不等于parent_id的消息?

除非删除实际线程(引用消息表对话的MessageThreads表),否则我可以安排从不允许删除parent_id行。

在运行delete_all方法时,我怎么能这样做才能忽略这个父行?

亲切的问候

4 个答案:

答案 0 :(得分:16)

如今在Rails 4中,您可以这样做:

Model.where.not(attr: "something").delete_all

Model.where.not(attr: "something").destroy_all

不要忘记差异:

  • destroy_all:通过调用destroy方法将相关对象与此对象一起销毁。实例化所有记录并一次销毁一个,因此对于大型数据集,这可能会很慢
  • delete_all:立即销毁所有关联对象,而不调用其destroy方法。不会调用回调。

答案 1 :(得分:2)

为什么不使用父记录中的关联,比如这样?

Message.where(:id => parent_id).first
  .children.where(:sender_status => 1, :recipient_status => 1)
  .delete_all

答案 2 :(得分:2)

这最终对我有用。

Message.where('id != ? AND parent_id = ?', parent_id, parent_id).where(:sender_status => 1, :recipient_status => 1).delete_all

除了id == parent_id之外,基本上返回该特定会话的所有消息。无论id == parent_id,这意味着它是父消息。

答案 3 :(得分:1)

我会考虑采用略有不同的方法,并使has_many关系的模型与:dependent => destroy对应,例如
User has_many :messages, :dependent => :destroy 这样你就不会得到你所描述的“悬空孤儿记录”问题。

我会尝试以这种方式接近它,而不是考虑'除了'之外的所有记录 我不知道是否有一些我没有解决的问题,但这就是所描述的问题。