为什么ActiveRecord的delete_all会在内部事务中触发单个查询?

时间:2018-03-27 11:07:50

标签: ruby-on-rails activerecord

我有这个方法:

# app/models/calendar.rb
has_many :events

def update_and_recreate_events
  ActiveRecord::Base.transaction do
    self.events.delete_all
    update(params)
    Event.import!(build_events)
  end
end

为确保只有新记录有效才能删除记录,反之亦然,我将三种方法放在一个事务中。

delete_all应该使用一个查询删除表中的所有记录。但是,由于我在事务中使用delete_all,因此它会为每个记录触发一个删除查询。对于events中的每个事件,日志都会显示如下内容:

SQL (0.5ms)  DELETE FROM "events" WHERE "events"."id" = $1  [["id", 73391]]

我不知道它为什么会这样,也许我遇到了一些非常基本的错误。

修改

为避免误解,请考虑以下事项:

我不想删除中的所有记录,但是与当前对象相关联的所有记录。因此:self.events.delete_all

正如documentation for delete_all所述:

  

这是一个直接访问数据库的SQL DELETE语句,比destroy_all更有效。

为什么我的情况不起作用?

2 个答案:

答案 0 :(得分:0)

你需要写

Event.delete_all

这将生成一行查询

DELETE FROM "event";

我不是因为它指的是Klass类的主要对象而无法调用self。

请解释一下?

更新并尝试回答

据我了解,您需要添加

has_many :events, dependent: :delete__all

答案 1 :(得分:-3)

因为ActiveRecord使用DELETE FROM进行delete_alldestroy_all方法,这就是此运算符的工作方式。

要使用一个查询删除所有表记录,SQL应使用TRUNCATE。 Rails示例如下:

Model.connection_pool.with_connection { |c| c.truncate(Model.table_name) }