2015-10-19 2 views
0

У меня есть что-то вроде следующего цикла, который создает много вставок:Как навальная вставка с Arel?

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 

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

PS: обратите внимание, что я не хочу писать строки sql (проблемы безопасности).

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(????) 

ответ

0

Глядя на bulk_insert (спасибо @Gavin Miller), я понял, что они используют Rails cote, который предотвращает инъекции sql.

Потому что мне нужно что-то настроенное, я не собираюсь за драгоценный камень. Итак, мое окончательное решение ниже, если у кого-то аналогичное требование:

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) 
2

Был библиотека, которая вышла в начале этого месяца называется bulk_insert. Это должно обеспечить вас с функциональностью, которую вы ищете:

Model.bulk_insert do |worker| 
    worker.add(...) 
    worker.add(...) 
    ... 
end 

# Produces: 
INSERT INTO models (...) VALUES 
    (...), 
    (...), 
    (...), 
    (...), 
    ... 

Как это довольно новая библиотека, и я не имел возможности играть с ним, я неопределенными на это возможности AREL.