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
How would I save multiple records at once in Rails?
提问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.
通过这种方式,您将检索一个数组,true并false知道哪些成功了,哪些没有。
回答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

