Saving multiple objects in a single call in rails
insert_all (Rails 6+)
Rails 6
introduced a new method insert_all, which inserts multiple records into the database in a single SQL INSERT
statement.
Also, this method does not instantiate any models and does not call Active Record callbacks or validations.
So,
Foo.insert_all([
{ first_name: 'Jamie' },
{ first_name: 'Jeremy' }
])
it is significantly more efficient than
Foo.create([
{ first_name: 'Jamie' },
{ first_name: 'Jeremy' }
])
if all you want to do is to insert new records.
Since you need to perform multiple inserts, database will be hit multiple times. The delay in your case is because each save is done in different DB transactions. You can reduce the latency by enclosing all your operations in one transaction.
class Foo
belongs_to :parent, :class_name => "Foo"
has_many :children, :class_name => "Foo", :foreign_key=> "parent_id"
end
Your save method might look like this:
# build the parent and the children
a = Foo.new(:name => "bar")
a.children.build(:name => "123")
b = Foo.new("baz")
b.children.build(:name => "zxy")
#save parents and their children in one transaction
Foo.transaction do
a.save!
b.save!
end
The save
call on the parent object saves the child objects.
You might try using Foo.create instead of Foo.new. Create "Creates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not."
You can create multiple objects like this:
# Create an Array of new objects
parents = Foo.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
Then, for each parent, you can also use create to add to its association:
parents.each do |parent|
parent.children.create (:child_name => 'abc')
end
I recommend reading both the ActiveRecord documentation and the Rails Guides on ActiveRecord query interface and ActiveRecord associations. The latter contains a guide of all the methods a class gains when you declare an association.