【问题标题】:Find or Create Multiple Records in Ruby on Rails - "find_or_create_all"在 Ruby on Rails 中查找或创建多条记录 - “find_or_create_all”
【发布时间】:2010-07-07 01:01:55
【问题描述】:

在 Rails 中执行“find_or_create_all”的一种高效且优雅的方式是什么?

鉴于:
姓名 = ["鲍勃","约翰","杰克","席德"],
用户表

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

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

中间解决方案 - ["#User:0x3ae3a00", nil, nil, "#User:0x3ae37f8"] 也可以,例如,如果用户表中只存在第一个和第四个条目。

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

【问题讨论】:

    标签: mysql ruby-on-rails


    【解决方案1】:

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

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

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

    【讨论】:

    • 我想在 Rails 中创建模型的多个实例,但找不到干净的方法。但是您到 ar-extensions gem 的链接很有帮助。谢谢 Sid
    【解决方案2】:

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

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

    这将返回一个用户对象数组。

    【讨论】:

    • 感谢您的回复,但问题是如果数组长度为 1000,它将对数据库进行 1000 次单独查询。如果这样的事情每 5 分钟在一个 cron 作业中运行一次,它就会变得低效。进行单个查询(即 find_all_by_name)的问题是丢失数组中的位置。可以使用哈希映射回数组中的位置,但我希望有一种高效且优雅的方式。
    • 如果顺序是随机的,又想保持同样的随机顺序,不知道有什么好办法。如果有一些基于数据库表的订单,您可以使用User.find(:conditions => {:name => names}, :order => column_name)。或事后与 sort_by ruby-doc.org/core/classes/Enumerable.html#M003120.
    • 我还会检查您的数据库文档,看看您是否可以通过编写自己的 SQL 来做一些事情。
    【解决方案3】:

    在 Rails 6 中,现在有 upsert_all,我认为它处理得非常好。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2017-01-03
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      相关资源
      最近更新 更多