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_by
和where
方法的顺序很重要; 您必须在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?
方法使用就像你想要的