在Ruby on Rails中查找或创建多个记录 - “find_or_create_all”

时间:2010-07-07 01:01:55

标签: mysql ruby-on-rails

在rails中执行“find_or_create_all”的有效且优雅的方法是什么?

鉴于:
names = [“Bob”,“John”,“Jack”,“Sid”],
用户表

需要:
users = [“#User:0x3ae3a00”,“#User:0x3ae3938”,“#User:0x3ae3898”,“#User:0x3ae37f8”]

仅当用户不存在时才创建用户。

中间解决方案 - [“#User:0x3ae3a00”,nil,nil,“#User:0x3ae37f8”]也会这样做,例如,如果只有第一个和第四个条目存在于Users表中。

一种方法是使用find_all_by_name并使用哈希映射回名称数组中的条目,但我想知道在rails中是否有一种优雅而有效的方式。

3 个答案:

答案 0 :(得分:1)

ar_extensions提供了一个很好的解决方案。 https://github.com/zdennis/ar-extensions

假设有问题的表有一个具有唯一数据库索引的列,如果唯一列上没有匹配项,则可以使用批量插入来插入,如果唯一列上存在匹配项,则跳过或更新行

在envycasts中加载大型数据集涵盖了这种情况http://envycasts.com/products/advanced-activerecord

答案 1 :(得分:0)

如果我理解并且您想要获取一系列名称并将其转换为用户数组?

names = ["Bob","John","Jack","Sid"]
users = names.map{|name| User.find_or_create_by_name(name)}

将返回一组用户对象。

答案 2 :(得分:0)

在 Rails 6 中,我认为现在 upsert_all 可以很好地处理这个问题。

Book.upsert_all([
  { title: "Rework", author: "David", isbn: "1" },
  { title: "Eloquent Ruby", author: "Russ", isbn: "1" }
], unique_by: :isbn)