ActiveRecord Rails - 创建一批空记录



在我的rails应用程序中,我有一个模型,说"服务器",它有很多"虚拟机"。当服务器记录配置为具有 50 个虚拟机时,我希望立即创建 50 个虚拟机的空记录。 1) 编号: 1, start_time: 无, 空格: 无 2) 编号: 2, start_time: 无, 空格: 无 3) id: 3, start_time: 无, 空格: 无 4) 编号: 4, start_time: 无, 空格: 无 ... 50) 编号: 50, start_time: 无, 空格: 无

我知道这可以通过 for 循环和创建/新建来实现。但是,有没有一种 ActiveRecord 方法可以在没有循环的情况下执行此操作,以便减少从我的应用程序到数据库的调用次数?

谢谢 格雷格

看看 activerecord-import gem。它处理您描述的批量插入,同时将 ActiveRecord 查询的数量保持在最低限度。在后台作业中执行此操作可能是个好主意,因为您要创建如此多的记录。

如果要创建没有实际数据的多个记录,则需要编写一个一次插入所有记录的SQL查询,而不是使用将创建50个单独查询的.create

ActiveRecord 没有针对批量插入的内置规定。您可以使用 gem 或编写自己的 gem,这对于此用例来说非常微不足道。

您可以一次插入多行,如下所示:

INSERT INTO virtual_machines (server_id) VALUES (1), (1),...

您可以使用简单的字符串操作来添加所有这些值:

"INSERT INTO virtual_machines (server_id) VALUES " + Array.new(50, "(#{id})").join(', ')

您应该能够忽略所有没有值的列,因为它们无论如何都应该由数据库默认值处理。

要执行 SQL 语句,请使用self.connection.execute。将其包装在事务中可能是谨慎的:

class Server < ApplicationRecord
def self.create_with_children(**attributes)
self.transaction do
record = self.create!(attributes)
self.connection.execute(
'INSERT INTO virtual_machines (server_id) VALUES ' + 
Array.new(50, "(#{record.id})").join(',')
)
record
end
end
end

由于它是单个查询,因此执行时间很可能与插入单行相当,并且使用后台作业是过早优化。

最新更新