Rails:在has-many-through关系中创建一个'through'记录,不带N + 1

时间:2017-06-23 16:47:41

标签: ruby-on-rails ruby activerecord ruby-on-rails-5

这非常令人沮丧...我在联接表上与has_many :through字段有一个非常简单的_type关系:

Subscriber
has_many :books
has_many :books, through: :selected_books

SelectedBook
belongs_to :book
belongs_to :subscriber
**_type** field

Book
has_many :selected_books
has_many :subscribers, through: :selected_books

我正在尝试创建一个具有特定类型的SelectedBook ...我正在尝试实际创建数千个。

我有一个book_idssubscriber_id的数组。

我想这样做......

  params[:book_ids].each do |book_id|
    current_user.selected_books.create!(_type: 'rental', book_id: book_id)
  end

基本上我想尽快插入所有记录(我不需要实例化它,我也不需要回调)。

虽然对于每一个插页都会做一个愚蠢的N + 1.

我怎样才能做100次插入(我试图避免使用原始SQL)。

我在我的应用程序的另一部分中像这样解决了它:

@subscriber.regions << Region.where(id: params[:region_ids])

这很好用,因为它只有一个SELECT * FROM regions WHERE id IN(1,2,3,4,5),所以它只是一个查询。

问题是,在这种情况下,我还需要为_type

插入额外的SelectedBook

1 个答案:

答案 0 :(得分:1)

我认为你可以这样做:

params[:book_ids].each do |book_id|
  SelectedBook.create!(_type: 'rental', book_id: book_id, subscriber_id: current_user.id)
end

但是我会做一个批量插入...我知道你试图避免使用原始SQL,但它会生成一个SQL插入语句:

conn = ActiveRecord::Base.connection
inserts = []
params[:book_ids].each do |book_id|
  inserts << %{(
    #{conn.quote(book_id)},
    #{conn.quote(current_user.id)},
    #{conn.quote('rental')}
  )}
end
sql = %{
  INSERT INTO selected_books
  (book_id, subscriber_id, _type)
  VALUES #{inserts.join(',')}
}
conn.execute(sql)