Boj*_*jan 46 database null ruby-on-rails
检查数据库在处理之前是否返回记录的最有效方法是什么.例:Truck.where("id = ?", id).select('truck_no').first.truck_no
如果卡车存在,这可能会或可能不会返回卡车.在处理此请求时,确保页面不会崩溃的最有效方法是什么.如果让我说我使用循环来浏览每辆卡车并打印出它的编号,我将如何在视图和控制器中处理这个问题.
如果记录不存在,我希望能够打印出一条消息,而不是说没有找到记录.
cri*_*ian 97
如果要检查对象的存在,为什么不使用存在?
if Truck.exists?(10)
# your truck exists in the database
else
# the truck doesn't exist
end
Run Code Online (Sandbox Code Playgroud)
该exists?方法的优点是不从数据库中选择记录(意味着比选择记录更快).查询看起来像:
SELECT 1 FROM trucks where trucks.id = 10
Run Code Online (Sandbox Code Playgroud)
您可以在http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F找到更多示例.
Sha*_*nak 35
这是你如何检查这个.
if Trucks.where(:id => current_truck.id).blank?
# no truck record for this id
else
# at least 1 record for this truck
end
Run Code Online (Sandbox Code Playgroud)
where方法返回一个ActiveRecord :: Relation对象(就像一个包含where的结果的数组),它可以是空的但永远不会是nil.
OP实际用例解决方案
最简单的解决方案是将数据库检查和数据检索组合到1个DB查询中,而不是单独的数据库调用.您的示例代码很接近并传达了您的意图,但实际语法中有点偏差.
如果您这么简单,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
Run Code Online (Sandbox Code Playgroud)
我建议使用"注释"本身的干净语法,以便其他人确切地知道您正在尝试做什么.
如果你真的想加倍努力,你可以为你的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
Run Code Online (Sandbox Code Playgroud)
然后你会这样称呼它:
if truck_number = Truck.truck_number_if_exists(id)
# do processing because record exists and you have the value
else
# no matching criteria
end
Run Code Online (Sandbox Code Playgroud)
该ActiveRecord.find_by方法将检索与您的条件匹配的第一条记录,否则nil如果未找到具有该条件的记录则返回.请注意,find_by和where方法的顺序很重要; 你必须打电话select给Truck模特.这是因为当你调用where方法时,你实际上正在返回一个ActiveRelation不是你想要的对象.
有关'find_by'方法,请参阅ActiveRecord API
使用'存在?'的一般解决方案 方法
正如其他一些贡献者已经提到的那样,该exists?方法专门用于检查某些东西的存在.它不返回值,只是确认DB具有符合某些条件的记录.
如果您需要验证某些数据的唯一性或准确性,这将非常有用.好的部分是它允许您使用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
这比实际返回数据更有效.
如果您需要实际有条件地从数据库中检索数据,则这不是要使用的方法.但是,它非常适合简单检查,语法非常清晰,因此其他开发人员确切知道您正在做什么.在具有多个开发人员的项目中,使用适当的语 编写干净的代码,让代码"注释"自己.