假设我有User
& Bonus
个模型
class User < ActiveRecord::Base
has_many :bonuses
end
class Bonus < ActiveRecord::Base
belongs_to :user
end
IE我想为用户创建具有相同参数的n
奖励。最简单的方法是:
n.times { u.bonuses.create!(params) }
但这会触发n
次交易,如果n
相对较大,可以安静地浏览。
如何通过activerecord(非原始sql)在一次交易中创建所有这些奖金?
答案 0 :(得分:2)
create
方法允许散列数组作为参数。要在一个事务中创建它,请将其transaction
块包装:
$> attributes = Hash[:title, "foo", :about, "bar"]
$> a = User.last
没有交易:
$> a.bonuses.create((1..6).map{ attributes })
(0.2ms) BEGIN
SQL (0.5ms) INSERT INTO
.......
(11.2ms) COMMIT
(0.1ms) BEGIN
SQL (0.4ms) INSERT INTO
.......
(6.5ms) COMMIT
(0.1ms) BEGIN
SQL (0.3ms) INSERT INTO
.......
(6.9ms) COMMIT
(0.1ms) BEGIN
SQL (0.3ms) INSERT INTO
.......
(6.8ms) COMMIT
使用交易:
$> User.transaction { a.bonuses.create((1..6).map{ attributes }) }
# a.bonuses.transaction { a.bonuses.create((1..6).map{ attributes }) }
(0.2ms) BEGIN
SQL (0.5ms) INSERT INTO
..............
SQL (1.3ms) INSERT INTO
..............
SQL (0.3ms) INSERT INTO
..............
SQL (0.3ms) INSERT INTO
..............
SQL (0.2ms) INSERT INTO
..............
SQL (0.2ms) INSERT INTO
(12.8ms) COMMIT
答案 1 :(得分:1)
我认为你可以使用ActiveRecord Import gem:
bonuses = n.times.map { u.bonuses.build(params) }.flatten
Bonus.import(bonuses)
它只对数据库执行一次操作。我不知道它是否会复制或者它会进行大插入,但这比使用普通的AR功能快得多。
答案 2 :(得分:0)
create
方法接受数组。您可以使用参数创建一个数组,并将其传递给create
方法。
例如:
u.bonuses.create!(Array.new(n){params})
希望能帮到你。