ruby-on-railsactiverecorddata-access

Saving multiple objects in a single call in rails


I have a method in rails that is doing something like this:

a = Foo.new("bar")
a.save

b = Foo.new("baz")
b.save

...
x = Foo.new("123", :parent_id => a.id)
x.save

...
z = Foo.new("zxy", :parent_id => b.id)
z.save

The problem is this takes longer and longer the more entities I add. I suspect this is because it has to hit the database for every record. Since they are nested, I know I can't save the children before the parents are saved, but I would like to save all of the parents at once, and then all of the children. It would be nice to do something like:

a = Foo.new("bar")
b = Foo.new("baz")
...
saveall(a,b,...)

x = Foo.new("123", :parent_id => a.id)
...
z = Foo.new("zxy", :parent_id => b.id)
saveall(x,...,z)

That would do it all in only two database hits. Is there an easy way to do this in rails, or am I stuck doing it one at a time?


Solution

  • 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.