检查数据库在处理之前是否返回记录的最有效方法是什么。示例:Truck.where("id = ?", id).select('truck_no').first.truck_no
如果卡车存在,这可能会或可能不会返回卡车。在处理此请求时,确保页面不会崩溃的最有效方法是什么。如果让我说我使用循环来浏览每辆卡车并打印出它的数字,我将如何在视图和控制器中处理这个问题。
如果记录不存在,我希望能够打印出一条消息,而不是说找不到记录。
答案 0 :(得分:92)
如果要检查对象的存在,为什么不使用存在?
if Truck.exists?(10)
# your truck exists in the database
else
# the truck doesn't exist
end
exists?
方法的优点是不从数据库中选择记录(意味着比选择记录更快)。
查询如下所示:
SELECT 1 FROM trucks where trucks.id = 10
您可以在Rails documentation for #exists?中找到更多示例。
答案 1 :(得分:35)
以下是检查方法。
if Trucks.where(:id => current_truck.id).blank?
# no truck record for this id
else
# at least 1 record for this truck
end
其中方法返回一个 ActiveRecord :: Relation对象(就像一个包含where的结果的数组),它可以是空的但永远不会是nil。 / p>
答案 2 :(得分:8)
OP实际用例解决方案
最简单的解决方案是将数据库检查和数据检索合并到1个数据库查询中,而不是单独的数据库调用。您的示例代码很接近并传达了您的意图,但实际语法中的内容有点偏差。
如果您执行Truck.where("id = ?", id).select('truck_no').first.truck_no
并且此记录不存在,则在您致电nil
时会出现truck_no
错误,因为first
可能会检索nil
如果找不到符合您条件的记录,则记录。
这是因为您的查询将返回符合条件的对象数组,然后您对该数组执行first
(如果找不到匹配的记录)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
我建议使用干净的语法&#34; comments&#34;本身让其他人确切地知道你正在尝试做什么。
如果您真的想加倍努力,可以在Truck
课程中添加一个方法,为您完成此任务并传达您的意图:
# truck.rb model
class Truck < ActiveRecord::Base
def self.truck_number_if_exists(record_id)
record = Truck.select(:truck_no).find_by(record_id)
if record
record.truck_no
else
nil # explicit nil so other developers know exactly what's going on
end
end
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
方法的顺序很重要;您必须致电select
模型上的Truck
。这是因为当您调用where
方法时,您实际上会返回ActiveRelation
对象,而这不是您在此处寻找的对象。
See ActiveRecord API for 'find_by' method
使用&#39;的常规解决方案?&#39;方法强>
正如其他一些贡献者已经提到的那样,exists?
方法专门用于检查某些内容的存在。它没有返回值,只是确认数据库有一个符合某些条件的记录。
如果您需要验证某些数据的唯一性或准确性,这将非常有用。好的部分是它允许您使用ActiveRelation(Record?) where(...)
标准。
例如,如果您的User
模型具有email
属性,则需要检查dB中是否已存在电子邮件:
User.exists?(email: "test@test.com")
使用exists?
的好处是SQL查询运行
SELECT 1 AS one FROM "users" WHERE "users"."email" = 'test@test.com' LIMIT 1
比实际返回数据更有效。
如果您需要实际有条件地从数据库中检索数据,这不是要使用的方法。但是,它非常适合简单检查,语法非常清晰,因此其他开发人员确切知道您正在做什么。在具有多个开发人员的项目中,使用适当的语编写干净的代码并让代码&#34;评论&#34;本身。
答案 3 :(得分:2)
你可以这样做:
@truck_no = Truck.where("id = ?", id).pluck(:truck_no).first
如果未找到任何记录,则会返回nil
,否则将返回仅{/ 1>} 记录。
然后在你的视图中你可以做类似的事情:
truck_no
如果要获取并显示多个结果,请在控制器中:
<%= @truck_no || "There are no truck numbers" %>
并在您看来:
@truck_nos = Truck.where("id = ?", id).pluck(:truck_no)
答案 4 :(得分:0)
如果只想检查记录是否存在。与@cristian的答案一起使用,即
Truck.exists?(truck_id) # returns true or false
但是,如果卡车驶出,那么您想访问该卡车,则必须再次找到卡车,这将导致两个数据库查询。如果是这种情况,请
@trcuk = Truck.find_by(id: truck_id) #returns nil or truck
@truck.nil? #returns true if no truck is db
@truck.present? #returns true if no truck is db
答案 5 :(得分:-1)
Rails有persisted?
方法
像你想要的那样使用