Rails检查数据库中是否存在logging

检查数据库在处理之前是否会返回logging的方法是最有效的。 例如: Truck.where("id = ?", id).select('truck_no').first.truck_no

如果卡车存在,这可能会或可能不会返回卡车。 处理这个请求时,确保页面不会崩溃的最有效的方法是什么? 我如何处理这两个在视图和控制器,如果让我说,我使用循环通过每辆卡车,并打印出其编号。

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

如果你想检查一个对象的存在为什么不使用存在?

 if Truck.exists?(10) # your truck exists in the database else # the truck doesn't exists end 

exists? 方法的优点是不从数据库中selectlogging(意思是比selectlogging更快)。 该查询如下所示:

 SELECT 1 FROM trucks where trucks.id = 10 

您可以在http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3Ffind更多示例;

这里是你如何检查这个。

 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的结果),它可以是空的,但永远不会是零。

OP实际使用案例解决scheme

最简单的解决scheme是将数据库检查和数据检索合并为一个数据库查询,而不是单独的数据库调用。 你的示例代码很接近,expression了你的意图,但是在你的实际语法中有一点点关系。

如果你简单的做了Truck.where("id = ?", id).select('truck_no').first.truck_no并且这个logging不存在,当你打电话给truck_no时,它会抛出一个nil错误,因为first可能检索到nil如果没有find符合您的标准的logging。

这是因为你的查询将返回一个匹配你的条件的对象数组,然后你在那个数组上做first (如果没有find匹配的logging)是nil

相当干净的解决scheme:

 # 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 

我build议使用干净的语法来“评论”自己,以便其他人知道你正在做什么。

如果你真的想进一步,你可以添加一个方法到你的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方法将检索符合条件的第一条logging,否则返回nil如果在该条件下找不到logging。 请注意, find_bywhere方法的顺序很重要; 您必须在Truck模型上调用select 。 这是因为当你调用where方法时,你实际上返回了一个ActiveRelation对象,这不是你在这里寻找的东西。

查看ActiveRecord API的“find_by”方法

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

正如其他一些贡献者已经提到的那样,是否exists? 方法专门devise来检查某件事物的存在。 它不返回值,只是确认数据库有一个匹配一些条件的logging。

如果您需要validation某些数据的唯一性或准确性,这是非常有用的。 好的部分是它允许你使用ActiveRelation(Record?) where(...)条件。

例如,如果您有一个带有email属性的User模型,并且您需要检查dB中是否存在电子邮件:

User.exists?(email: "test@test.com")

使用的好处exists? 是SQL查询运行

SELECT 1 AS one FROM "users" WHERE "users"."email" = 'test@test.com' LIMIT 1

这比实际返回数据更有效率。

如果您需要从数据库中实际有条件地检索数据,则不是要使用的方法。 但是,它对于简单的检查非常有效,语法非常清晰,所以其他开发人员完全知道你在做什么。 使用适当的语法对于有多个开发人员的项 写干净的代码,让代码“评论”本身。

你可以做:

 @truck_no = Truck.where("id = ?", id).pluck(:truck_no).first 

如果找不到logging,则返回nil ,否则truck_no 第一个logging的truck_no

然后在你看来,你可以做一些事情:

 <%= @truck_no || "There are no truck numbers" %> 

如果你想获取并显示多个结果,那么在你的控制器中:

 @truck_nos = Truck.where("id = ?", id).pluck(:truck_no) 

并在你看来:

 <% truck_nos.each do |truck_no| %> <%= truck_no %> <% end %> <%= "No truck numbers to iterate" if truck_nos.blank? %> 

Rails有一个persisted? 方法使用就像你想要的