Honestly, has_and_belongs_to_many
is a very antiquated way of doing things. You should probably look into has_many :through
, which is the new way of doing join tables, and has been for quite some time.
class Foo < ActiveRecord::Base
has_many :foobars
has_many :bars, :through => :foobars
def add_many_bars(bars)
bars.each do |bar|
self.bars << bar
end
end
end
class Bar < ActiveRecord::Base
has_many :foobars
has_many :foos, :through => :foobars
end
class FooBar < ActiveRecord::Base
belongs_to :foo
belongs_to :bar
end
Also, you should try running the same in production and see what kind of performance you get, as a lot of caching goes on in production that doesn't necessarily occur in development.
I think your best bet performance-wise is going to be to use SQL, and bulk insert multiple rows per query. If you can build an INSERT statement that does something like:
INSERT INTO foos_bars (foo_id,bar_id) VALUES (1,1),(1,2),(1,3)....
You should be able to insert thousands of rows in a single query. I didn't try your mass_habtm method, but it seems like you could to something like:
bars = Bar.find_all_by_some_attribute(:a)
foo = Foo.create
values = bars.map {|bar| "(#{foo.id},#{bar.id})"}.join(",")
connection.execute("INSERT INTO foos_bars (foo_id, bar_id) VALUES #{values}")
Also, if you are searching Bar by "some_attribute", make sure you have that field indexed in your database.