Ruby-on-rails 如何在 Rails 中一次保存多条记录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19081129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:46:21  来源:igfitidea点击:

How would I save multiple records at once in Rails?

ruby-on-railsruby

提问by Passionate Engineer

How would I save this array in one call with Rails?

如何使用 Rails 在一次调用中保存这个数组?

tax_rates = [{
  :income_from => 0
  :income_to  => 18200
  :start => "01-07-2013"
  :finish => "30-06-2014"
  :rate => nil
  :premium => nil
  },{
  :income_from => 18201
  :income_to  => 37000
  :start => "01-07-2013"
  :finish => "30-06-2014"
  :rate => 0.19
  :premium => nil
  },{
    :income_from => 18201
    :income_to  => 37000
    :start => "01-07-2013"
    :finish => "30-06-2014"
    :rate => 0.19
    :premium => nil
    }]

Can I just call Rails.create(tax_rates)?

我可以打电话Rails.create(tax_rates)吗?

Also, is there a way to remove duplicate symbols so they look neater?

另外,有没有办法删除重复的符号,使它们看起来更整洁?

采纳答案by apneadiving

A nice solution is to use the active record import gem. I recommend it over now builtin Rails bulk isert because its more flexible in the options in case of constraint violation.

一个不错的解决方案是使用活动记录导入 gem。我现在推荐它内置的 Rails 批量 isert,因为它在违反约束的情况下在选项中更加灵活。

TaxRate.import(
  [:income_from, :income_to, :start, :finish, :rate, :premium],
  tax_rates
)

Its definitely better than my old answer which would trigger a db commit per entry in the array :)

它绝对比我的旧答案更好,后者会触发数组中每个条目的数据库提交:)



Old answer:

旧答案:

tax_rates.map {|tax_rate| TaxRate.new(tax_rate).save } 

This way you'll retrieve an array with trueand falseto know which did succeed and which didn't.

通过这种方式,您将检索一个数组,truefalse知道哪些成功了,哪些没有。

回答by Dennis

Your example is almost correct.

你的例子几乎是正确的。

Use ActiveRecord::Persistence#create, which can accept an array of hashes as a parameter.

使用ActiveRecord::Persistence#create,它可以接受散列数组作为参数。

tax_rates = [
  {
    income_from: 0,
    income_to: 18200,
    start: "01-07-2013",
    finish: "30-06-2014",
    rate: nil,
    premium: nil,
  },
  {
    income_from: 18201,
    income_to: 37000,
    start: "01-07-2013",
    finish: "30-06-2014",
    rate: 0.19,
    premium: nil,
  },
  # ...
]

TaxRate.create(tax_rates)  # Or `create!` to raise if validations fail

回答by skadoosh

If you want all of them to be saved .or, non of them to be saved even if one fails, you can use 'ActiveRecord::Base.transaction'

如果您希望所有这些都被保存。或者,即使一个失败也不会保存它们,您可以使用“ActiveRecord::Base.transaction”

e.g.

例如

ActiveRecord::Base.transaction do  
   tax_rate.each do |tax_rt|  
       TaxRate.new(tax_rt).save  
    end
 end

回答by user3209457

I am not sure about rails < 4.2 but I have tried it in rails 4.2 you can simply do this

我不确定 rails < 4.2 但我已经在 rails 4.2 中尝试过你可以简单地做到这一点

TaxRate.create(tax_rt)

回答by kiriloff

Here is an example like yours:

这是一个像你这样的例子:

a = []

a << B.new(:name => "c")
a << B.new(:name => "s")
a << B.new(:name => "e")
a << B.new(:name => "t")

The array is saved all at once with:

数组一次性保存:

a.each(&:save)

This will call B#saveon each item in the array.

这将调用B#save数组中的每个项目。

回答by val caro

use a gem 'fast_inserter': https://github.com/joinhandshake/fast_inserter

使用 gem 'fast_inserter':https: //github.com/joinhandshake/fast_inserter

it generates a single sql query of thousand records.

它生成一个包含数千条记录的 sql 查询。

movie_data = [1, 'Climates (Iklimler)', 'Clay Pauwel', 'Drama'],
          [2, 'Tinpis Run', 'Andros Glazer', 'Comedy'],
          [3, 'Naked City, The', 'Bethena Chatband', 'Mystery'],
          [4, 'Small Time Crooks', 'Naomi Plom', 'Crime'],
          [5, 'Shadowboxer', 'Georgeanne Widdicombe', 'Thriller']

    params = {
      table: 'movies',
        static_columns: {
          created_at: '0000-00-00 00:00:00',
          updated_at: '0000-00-00 00:00:00',
        },
      options: {
        timestamps: false,
        unique: true,
        check_for_existing: true
      },
        group_size: 100,
        variable_columns: %w(id title director description),
        values: movie_data
    }
    inserter = FastInserter::Base.new(params)
    inserter.fast_insert