简体   繁体   English

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

[英]Find or Create Multiple Records in Ruby on Rails - “find_or_create_all”

What is an efficient and elegant way of performing a "find_or_create_all" in rails?在 Rails 中执行“find_or_create_all”的有效而优雅的方式是什么?

Given:鉴于:
names = ["Bob","John","Jack","Sid"],姓名 = ["鲍勃","约翰","杰克","席德"],
Users table用户表

Needed:需要:
users = ["#User:0x3ae3a00", "#User:0x3ae3938", "#User:0x3ae3898", "#User:0x3ae37f8"]用户 = ["#User:0x3ae3a00", "#User:0x3ae3938", "#User:0x3ae3898", "#User:0x3ae37f8"]

where a user is created only if it doesn't exist.仅当用户不存在时才创建该用户。

An intermediate solution - ["#User:0x3ae3a00", nil, nil, "#User:0x3ae37f8"] will also do, if for example only the first and fourth entries exist in the Users table.一个中间解决方案 - ["#User:0x3ae3a00", nil, nil, "#User:0x3ae37f8"] 也可以,例如,如果用户表中只存在第一个和第四个条目。

One way is to use a find_all_by_name and use a hash to map back to the entries in the names array but I wonder if there is an elegant yet efficient way in rails.一种方法是使用 find_all_by_name 并使用哈希映射回名称数组中的条目,但我想知道在 rails 中是否有一种优雅而有效的方法。

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

Assuming the table in question has a column with a unique database index, bulk inserts can be used to insert if there isn't a match on the unique column and skip or update the row if there is a match on the unique column.假设有问题的表有一个具有唯一数据库索引的列,如果唯一列上没有匹配项,则可以使用批量插入进行插入,如果唯一列上有匹配项,则跳过或更新该行。

Loading large datasets at envycasts covers this case http://envycasts.com/products/advanced-activerecord在 envycasts 加载大型数据集涵盖了这种情况http://envycasts.com/products/advanced-activerecord

If I understand and you want to take an array of names and convert it into an array of users?如果我理解并且您想获取一组名称并将其转换为一组用户?

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

that will return an array of user objects.这将返回一组用户对象。

In Rails 6 there is now upsert_all which I think handles this super well.在 Rails 6 中,我认为现在upsert_all可以很好地处理这个问题。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM