Подтвердить что ты не робот

Как реализовать объемную вставку в Rails 3

Мне нужно вставить массив писем в разные записи в таблицу контактов. Как это можно сделать.

Eg: @email = ["[email protected]", "[email protected]", "[email protected]", ... ]

Я не хочу использовать.

  @email.each do |email|
     @contact = Contact.new
     @contact.email = email
     @contact.save
  end

Эта причина n вставляет запросы. Мне просто нужен один запрос на вставку, чтобы вставить эти значения. Как это можно сделать в rails 3.0.9 (и в идеале MySQL). Пожалуйста, помогите

4b9b3361

Ответ 1

activerecord-import реализует импорт AR #

activerecord-import - это библиотека для массовой вставки данных с использованием ActiveRecord.

посмотреть, как это работает:

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

Дом проекта находится на Github и wiki.

Ответ 2

Вы также можете попробовать upsert, который примерно так же быстро, как activerecord-import, но работает только (в настоящее время) с MySQL, Postgres, и SQLite3:

require 'upsert'
Upsert.batch(Contact.connection, Contact.table_name) do |upsert|
  emails.each do |email|
    upsert.row(email: email)
  end
end

Обратите внимание, что это связано с одним запросом базы данных на запись, но это "upsert", поэтому вам не нужно проверять, существует ли запись. В вашем примере это не проблема, но в большинстве приложений она становится в конечном итоге.

Ответ 3

Простейшим способом без дополнительного gem является конкатция строки и ее выполнение в одной вставке SQL (http://www.electrictoolbox.com/mysql-insert-multiple-records/).

@email = ["[email protected]", "[email protected]", "[email protected]"]

time = Time.current.to_s(:db)

values = @email.map do |email|
  "('#{email}', '#{time}', '#{time}')"
end

sql = "INSERT INTO contacts (email, created_at, updated_at) VALUES #{values.join(', ')}"
Contact.connection.execute(sql)