Ruby on rails Rails检查数据库中是否存在记录

Ruby on rails Rails检查数据库中是否存在记录,ruby-on-rails,database,null,Ruby On Rails,Database,Null,在处理记录之前,检查数据库是否返回记录的最有效方法是什么。示例:Truck.where(“id=?”,id)。选择(“Truck\u no”)。首先。Truck\u no 如果卡车存在,这可能返回卡车,也可能不返回卡车。对于我来说,什么是确保页面在处理此请求时不会崩溃的最有效方法。如果假设我使用一个循环遍历每辆卡车并打印出其编号,我将如何在视图和控制器中处理此问题 如果记录不存在,我希望能够打印出一条消息,而不是说找不到记录。以下是您可以检查的方法 if Trucks.where(:id =&g

在处理记录之前,检查数据库是否返回记录的最有效方法是什么。示例:
Truck.where(“id=?”,id)。选择(“Truck\u no”)。首先。Truck\u no

如果卡车存在,这可能返回卡车,也可能不返回卡车。对于我来说,什么是确保页面在处理此请求时不会崩溃的最有效方法。如果假设我使用一个循环遍历每辆卡车并打印出其编号,我将如何在视图和控制器中处理此问题


如果记录不存在,我希望能够打印出一条消息,而不是说找不到记录。

以下是您可以检查的方法

if Trucks.where(:id => current_truck.id).blank?
  # no truck record for this id
else
  # at least 1 record for this truck
end
where方法返回一个ActiveRecord::Relation对象(就像一个包含where结果的数组),它可以为空,但不能为零。

您可以执行以下操作:

@truck_no = Truck.where("id = ?", id).pluck(:truck_no).first
如果未找到任何记录,则返回
nil
,否则仅返回第一条记录的
truck\u no

在你看来,你可以这样做:

<%= @truck_no || "There are no truck numbers" %>
在你看来:

<% truck_nos.each do |truck_no| %>
  <%= truck_no %>
<% end %>

<%= "No truck numbers to iterate" if truck_nos.blank? %>

如果要检查对象是否存在,为什么不使用exists

if Truck.exists?(10)
  # your truck exists in the database
else
  # the truck doesn't exist
end
存在?
方法的优点是不从数据库中选择记录(这意味着比选择记录更快)。 查询如下所示:

SELECT 1 FROM trucks where trucks.id = 10

您可以在。

OP实际用例解决方案中找到更多示例

最简单的解决方案是将数据库检查和数据检索合并到1db查询中,而不是单独进行DB调用。您的示例代码很接近,并且传达了您的意图,但是它与您的实际语法有点不符

如果您只需执行
Truck.where(“id=?”,id)。选择('Truck\u no')。first.Truck\u no
并且此记录不存在,则在调用
Truck\u no
时,它将抛出
nil
错误,因为
first
可以检索
nil
记录,前提是未找到符合您的条件

这是因为您的查询将返回一个与您的条件匹配的对象数组,然后您首先对该数组执行
操作,该数组(如果未找到匹配记录)为
nil

一个相当干净的解决方案:

# Note: using Rails 4 / Ruby 2 syntax
first_truck = Truck.select(:truck_no).find_by(id) # => <Truck id: nil, truck_no: "123"> OR nil if no record matches criteria

if first_truck
  truck_number = first_truck.truck_no
  # do some processing...
else
  # record does not exist with that criteria
end
那么你可以这样称呼它:

if truck_number = Truck.truck_number_if_exists(id)
  # do processing because record exists and you have the value
else
  # no matching criteria
end
ActiveRecord.find_by
方法将检索与您的条件匹配的第一条记录,如果没有找到符合该条件的记录,则返回
nil
。请注意,
find_by
的顺序,其中
方法很重要;您必须调用
卡车
型号上的
选择
。这是因为当您调用
where
方法时,实际上返回的是一个
ActiveRelation
对象,而不是您在这里寻找的对象

使用“存在”方法的一般解决方案

正如其他一些贡献者已经提到的那样,
exists?
方法是专门设计用来检查某物是否存在的。它不返回值,只是确认DB有一条符合某些条件的记录

如果您需要验证某个数据段的唯一性或准确性,那么它非常有用。好的方面是它允许您使用
ActiveRelation(Record?)where(…)
标准

例如,如果您的
用户
模型具有
电子邮件
属性,并且您需要检查数据库中是否已经存在电子邮件:

用户。是否存在?(电子邮件:test@test.com“”

使用
的好处在于可以运行SQL查询

从“用户”中选择1,其中“用户”。“电子邮件”='test@test.com'限制1

这比实际返回数据更有效

如果您实际需要有条件地从数据库中检索数据,那么这不是要使用的方法。但是,它非常适合于简单的检查,语法非常清晰,因此其他开发人员可以确切地知道您在做什么。在有多个开发人员的项目中,使用适当的语法是至关重要的。编写干净的代码,让代码自己“注释”。

Rails有一个方法
如果您只想检查记录是否存在,请按您的意愿使用。按照克里斯蒂安的回答去做

Truck.exists?(Truck_id)#返回真或假

但如果卡车存在,并且您希望访问该卡车,则必须再次找到卡车,这将导致两个数据库查询。如果是这样的话,你就去吧

@truck = Truck.find_by(id: truck_id) #returns nil or truck
@truck.nil? #returns true if no truck in db
@truck.present? #returns true if no truck in db

您使用的是哪个版本的rails?请查看现有版本?方法可能的重复我一直认为它会返回一个零。谢谢你澄清这一点。@不管是谁投了反对票。请添加注释,以帮助理解此处的错误。使用
存在?
插入
空白?
。这将执行一个查询来检查数据库中是否存在对象,而不是检索整个对象。在RubyonRails中,任何以问号“?”结尾的函数都返回布尔值,即true或false。无论它是
存在?
还是
空白?
@ImranNaqvi使用
空白?
可能会更糟糕,因为它将在检查
是否存在任何记录之前返回所有记录。
限制1
添加到sql语句中,这样最多只能加载一条记录。请看下面的@cristian的答案。谢谢你的建议。我从来不知道拔毛法,不用谢
Pulk
将从表中选择一列。在ruby中,任何返回true或false的函数都是
truck\u number\u(如果存在)(id)
,则在end@ImranNaqvi:Ruby中的约定是将
附加到布尔方法,这是正确的;但是,在这种情况下,
truck\u number\u如果存在(id)
不是布尔方法;如果存在,则返回一个值,否则返回nil。由于它不是布尔方法,因此不应在末尾使用
pe
if truck_number = Truck.truck_number_if_exists(id)
  # do processing because record exists and you have the value
else
  # no matching criteria
end
@truck = Truck.find_by(id: truck_id) #returns nil or truck
@truck.nil? #returns true if no truck in db
@truck.present? #returns true if no truck in db