从ActiveRecord / Rails查询中检索单个记录

我发出如下的查询,完全检索0或1条记录:

car = Car.where(vin: '1234567890abcdefg') 

返回的当然是长度为1的汽车列表。所以我最终在查询结束时添加.first

 car = Car.where(vin: '1234567890abcdefg').first 

好像在Rails中应该有更好的方法。 是否存在类似.onlyOne东西,只返回一辆Car并且如果超过1则抛出exception?

 car = Car.where(vin: '1234567890abcdefg').onlyOne 

要么

 car = Car.onlyOne(vin: '1234567890abcdefg') 

Rails 4

你想要find_by(vin: 123) ,你可以通过find_by传递任何字段/值名称的散列来查找。

例如。

 Car.find_by(vin: '123') 

如果没有找到带有该vin的汽车,或者匹配该vin值的单辆汽车,则返回nil。 如果你添加一个爆炸(即find_by! ),如果没有找到带有该vin的汽车,它将引发exception。

如果您想要在发现多个错误时引发错误,那么您必须自己编写。 如果您不应该遇到多辆汽车具有相同vin的情况,那么最好的方法是使用Car模型的唯一性validation,例如。

 class Car < ActiveRecord::Base validates_uniqueness_of :vin # or validates :vin, unique: true end 

Rails 3

你想要find_by_vin (你可以用任何属性的名称替换vin

例如。

 Car.find_by_vin('123') 

如果没有找到带有该vin的汽车,或者具有该vin值的单辆汽车,则返回nil。 如果你添加一个爆炸(即find_by_vin! ),如果没有找到带有该vin的汽车,它将引发exception。

有关更多信息,请访问: http : //guides.rubyonrails.org/active_record_querying.html#retrieving-objects-from-the-database

 car = Car.find_by_vin('1234567890abcdefg') 

我不认为有什么东西可以抛出一个例外,但是在rails 4中有多个:

 car = Car.find_by(vin: '1234567890abcdefg') 

将返回唯一的一个。 强制唯一性的最佳方法是在模型/数据库级别上执行:

 class Car < ActiveRecord::Base validates :vin, uniqueness: true end 

如果由于某种原因,你确实需要在有多辆汽车的情况下抛出exception,你可以在模型上编写一个方法(或猴子补丁活动记录):

 class Car < ActiveRecord::Base class << self def only_one!(options) list = where(options) raise "Exactly one car isn't available" if list.size > 1 or list.size == 0 list.first end end end 

或使用一个问题:

 #lib/active_record_only_one.rb: module ActiveRecordOnlyOne extend ActiveSupport::Concern module ClassMethods def only_one!(options) list = where(options) raise "Exactly one isn't available" if list.size > 1 or list.size == 0 list.first end end end ActiveRecord::Base.send(:include, ActiveRecordOnlyOne) 

 #config/initializers/only_one.rb require "active_record_only_one" 

然后打电话:

 Car.only_one!(vuid: "1234567890abcdefg") 

你可以使用take and take!

 car = Car.where(vin: '1234567890abcdefg').take 

如果没有与给定字符串匹配的记录,则返回nil

 car = Car.where(vin: '1234567890abcdefg').take! 

如果没有与给定字符串匹配的记录,则返回ActiveRecord::RecordNotFound

来自指南(1.1.2,1.1.5和1.1.6)

 car = Car.take is equivalent to SELECT * FROM cars LIMIT 1