How to bulk insert with Arel?
Answer a question I have something like the following loop, which creates many inserts: table = Arel::Table.new(:users) users.each do |user| manager = Arel::InsertManager.new(ActiveRecord::Base) manag
Answer a question
I have something like the following loop, which creates many inserts:
table = Arel::Table.new(:users)
users.each do |user|
manager = Arel::InsertManager.new(ActiveRecord::Base)
manager.into(table).insert([
[table[:name], user.name],
[table[:created_at], user.created_at],
[table[:updated_at], user.updated_at]
])
# INSERT INTO users (name) VALUES ('a')
@conn.insert(manager.to_sql)
end
However, I would like to find a way to get only the values to be inserted. In this was I would be able to do a single insert for all values.
PS: please note I don't wan't to write sql strings (security concerns).
table = Arel::Table.new(:users)
inserts = []
users.each do |user|
manager = Arel::InsertManager.new(ActiveRecord::Base)
manager.into(table).insert([
[table[:name], user.name],
[table[:created_at], user.created_at],
[table[:updated_at], user.updated_at]
])
inserts << "(#{??manage values??})"
end
# INSERT INTO users (name) VALUES ('a'), ('b'), ('c')
@conn.insert(????)
Answers
Looking the bulk_insert (thanks to @Gavin Miller), I realised they use Rails cote that prevents sql injections.
Because I need something customised I'm not going for the gem. So, my final solution is below in case someone else has a similar requirement:
inserts = []
users.each do |user|
inserts << %{(
#{@conn.quote(user.name)},
#{@conn.quote(user.created_at)},
#{@conn.quote(user.updated_at)}
)}
end
sql = %{
INSERT INTO users
(name, created_at, updated_at)
VALUES #{inserts.join(',')}
}
@conn.execute(sql)
更多推荐
所有评论(0)