Search code examples
ruby-on-railsperformancehas-and-belongs-to-manymass-assignment

Rails-6: Mass import HABTM produces thousands inserts


After hours of googling for best practice, I came up here.

I have a new Foo object, and want to mass-assign thousands of bars to it, which I've pre-loaded:

@foo = Foo.create
@bars = Bar.find_all_by_some_attribute(:a)

What's the fastest way to do this? I've tried:

@foo.bars = @bars
@foo.bars << @bars

This results in thousands of insert queries being created.

Is there a Rails 6 (Insert_all) way to solve my issue or do I have to solve it with the "m2m_fast_insert" gem or hardcoded SQL?


Solution

  • If you have a Join table setup, like:

    class Item < ActiveRecord::Base
      has_and_belongs_to_many :orders
    end
    
    class Order < ActiveRecord::Base
      has_and_belongs_to_many :items
    end
    
    class ItemsOrders < ActiveRecord::Base
      belongs_to :item
      belongs_to :order
    end
    

    I believe you could insert many ItemOrders in this case (or whatever your join model is) with insert_all, which is new in Rails 6. If not your best bet is some amount of custom SQL. I did find another answer on SO that seemed to have a good starting point for the SQL: What is the fastest way to create mass HABTM associations in Rails?