13

在 Django 中,ORM 有一个被调用的函数get(),用于返回模型的单个实例。具体来说,如果在您只期望一个对象时返回多个对象,它会引发异常,因此它非常适合某些查找(即“使用此 slug 查找一篇文章”)。

我无法在 Rails/ActiveRecord 中找到具有相同行为的类似函数。到目前为止,我一直在编写如下代码:

Model.where( ... ).first

但这导致了返回一个对象的多个实例的静默错误——这确实是一个糟糕的、模棱两可的情况——我们只是抓住了第一个并继续进行,就像一切都好似的。

Active Record Query Interface 指南列出了 5 种检索单个对象的方法,其中最find()find_by()前途的,但当多个对象匹配搜索条件时,它们都不会引发异常。

我知道我可以自己编写where()find_by()查询并检查返回的对象数量,但是这段代码出现在我们的代码库中的任何地方,我宁愿不添加所有这些杂乱无章的东西。这似乎也是一种通用的、常见的需求,我希望它会被纳入 Rails/ActiveRecord 的某个地方。

是否有一些我缺少的功能可以更容易地捕捉这些情况?如果有帮助,我们正在使用 Rails 4 和 Ruby 2.0。

4

2 回答 2

5

Rails 7.0 为此引入find_sole_by(或where(...).sole)。

似乎完全符合要求:

查找唯一匹配的记录。ActiveRecord::RecordNotFound如果没有找到记录,则引发。ActiveRecord::SoleRecordExceeded如果找到多个记录,则引发。

用例很简单:

Model.find_sole_by(conditions: 'here')
于 2021-03-12T12:44:06.710 回答
2

我不知道内置的 Active Record 方法可以满足您的要求,但编写您自己的方法并不难。就像是:

class YourModel
  def self.find_only_one_by_slug(slug)
    results = YourModel.where(slug: slug)
    if results.size > 1
      raise "There should only be one return value."
    else
      return results.first
    end
  end
end

我没有测试上面的代码,所以肯定会有错误,但你明白了。您甚至可以更进一步,将类似的方法添加到所有模型都可以访问的活动记录库。

于 2013-11-05T17:39:25.373 回答