使用ActiveRecord 3/Arel查找单个记录的最佳方法?

Joh*_*hir 36 ruby activerecord ruby-on-rails arel

我曾经这样做过:

Foo.find_by_bar('a-value')
Run Code Online (Sandbox Code Playgroud)

我现在可以这样做:

Foo.where(:bar => 'a-value').limit(1).first
Run Code Online (Sandbox Code Playgroud)

这是推荐的吗?这是最好的方法吗?我应该继续使用"旧的"方式,因为它仍然是有用的语法糖,或者是否有更好的方式我现在可以做到这一点,这将支持链接和所有其他好东西?

Sur*_*hCS 45

导轨4:

Foo.find_by bar: 'a_value' , wibble: 'a wibble value'
Run Code Online (Sandbox Code Playgroud)


小智 22

我认为返回单个记录的首选方法与第二个示例相同,但您可以省略限制部分:

Foo.where(:bar => 'a-value').first
Run Code Online (Sandbox Code Playgroud)

如果要为查找添加更多条件,这将遵循新语法并支持链接.

  • 如果要确保找到记录,请使用`Foo.where(:bar =>'a-value')。first!`。这样,将以其他方式引发“ ActiveRecord :: RecordNotFound”。 (2认同)

SRa*_*ack 7

如果您需要且仅需要一条记录(我来这里是为了寻找),Rails 7.0为此引入了find_sole_by(或)。where(...).sole

行为如下:

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

用例很简单:

Foo.find_sole_by(bar: 'a-value')
Run Code Online (Sandbox Code Playgroud)

对于那些必须使用单个记录的场合非常方便。


Wil*_*ins 5

Rails 为您提供了一整套用于此类事情的神奇方法:

Foo.find_by_bar('a-value')
Run Code Online (Sandbox Code Playgroud)

您还可以使用多个属性:

Foo.find_by_bar_and_wibble('a foo value', 'a wibble value')
Run Code Online (Sandbox Code Playgroud)

并附加一个 ! 如果未找到任何内容,则会引发 RecordNotFound:

Foo.find_by_bar!('a-value')
Run Code Online (Sandbox Code Playgroud)

  • 从 Rails 4.0 开始,这些动态查找器已被弃用 (http://edgeguides.rubyonrails.org/4_0_release_notes.html#active-record-deprecations),因此现在学习可能不是一个好习惯。 (11认同)