如何使用Rails和单个insert语句在表中批量插入数据

时间:2014-06-24 16:47:48

标签: ruby-on-rails activerecord ruby-on-rails-3.2 arel

我有以下ActiveRecord模型,Widget,Merchant,Store,StoresWidget(多对多关联)

class Merchant < ActiveRecord::Base
  has_many :stores
  has_many :widgets
end

class Widget < ActiveRecord::Base
  has_many :stores_widgets
  has_many :stores, :through => :stores_widgets
  belongs_to :merchant
end

class Store < ActiveRecord::Base
  has_many :stores_widgets
  has_many :widgets, :through => :stores_widgets
  belongs_to :merchant
end

class StoresWidget < ActiveRecord::Base
  belongs_to :widget
  belongs_to :store
end

因此相应的表格为widgetsmerchantsstoresstores_widgets,其中widgetsstores各有{{1} }列和id有两列stores_widgetsstore_id。 Widget可以在一个或多个商店中使用,商店可以有许多小部件。有些小部件可在所有商店中使用,有些小部件仅在商店的子集中可用。如果窗口小部件仅限于商店的子集,则列widget_idrestricted

当新商店添加到商家时,我想更新与该商店相关联的所有不受限制的小部件。理想情况下,我希望在true

中包含这样的代码
StoresController#create

class StoresController < ApplicationController def create # build new store... Store.transaction do store.save! Widget.update_all_unrestricted_widgets_with_store(store) end render :show end end 最终执行SQL,如:

update_all_unrestricted_widgets_with_store

因此,如果商家拥有100000个不受限制的小部件,则会在一个INSERT中创建100000个新的store_widgets行,而不是100000个不同的INSERTS。

最好我想让ActiveRecord像这样构建一个插件。那可能吗?如果没有,我能用ARel做到这一点吗?我希望尽可能避免执行SQL字符串来实现这一点,这样我就可以在代码与数据库SQL语法分离的情况下保持一个级别。

1 个答案:

答案 0 :(得分:1)

您可以使用activerecord-import实现AR#import

activerecord-import是一个使用ActiveRecord批量插入数据的库。

了解它的工作原理:

books = []
10.times do |i| 
  books << Book.new(:name => "book #{i}")
end
Book.import books

参考 - https://github.com/zdennis/activerecord-import