在rails

时间:2015-06-13 07:54:19

标签: ruby-on-rails ruby activerecord

假设我有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)在一次交易中创建所有这些奖金?

3 个答案:

答案 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})

希望能帮到你。