检查数据库在处理之前是否会返回记录的最有效方法是什么?例如:Truck.where("id = ?", id).select('truck_no').first.truck_no
Rails检查数据库中是否存在记录
如果卡车存在,这可能会也可能不会返回卡车。处理此请求时,确保页面不会崩溃的最有效方法是什么?如果我可以说我正在使用一个循环遍历每辆卡车并打印出它的编号,我将如何在视图和控制器中处理这个问题。
如果记录不存在,我希望能够打印出消息,而不是说找不到记录。
检查数据库在处理之前是否会返回记录的最有效方法是什么?例如:Truck.where("id = ?", id).select('truck_no').first.truck_no
Rails检查数据库中是否存在记录
如果卡车存在,这可能会也可能不会返回卡车。处理此请求时,确保页面不会崩溃的最有效方法是什么?如果我可以说我正在使用一个循环遍历每辆卡车并打印出它的编号,我将如何在视图和控制器中处理这个问题。
如果记录不存在,我希望能够打印出消息,而不是说找不到记录。
如果你想检查一个对象的存在为什么不使用存在?
if Truck.exists?(10)
# your truck exists in the database
else
# the truck doesn't exists
end
的exists?
方法具有未从数据库中选择记录(意思是比选择记录更快)的优点。 查询看起来像:
SELECT 1 FROM trucks where trucks.id = 10
您可以在http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F
这里是你如何检查这个。
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对象(像它包含其中的结果的行为阵列),它可以是空的,但从来没有为零。
你可能只是做:
@truck_no = Truck.where("id = ?", id).pluck(:truck_no).first
这将返回nil
如果没有找到记录,或者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? %>
OP实际使用情况的解决方案
最简单的解决方案是你的数据库检查和检索数据合并到1找到更多的例子数据库查询,而不是分开的数据库调用。你的示例代码很接近并传达了你的意图,但是在你的实际语法中它有点不合适。
如果你简单做Truck.where("id = ?", id).select('truck_no').first.truck_no
这个记录不存在,就当你调用truck_no
因为first
可以检索nil
记录,如果没有找到符合条件的抛出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
我建议用干净的语法,“意见”本身让其他人知道你想要做什么。
如果你真的要多走一英里,你可以一个方法添加到您的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
方法的顺序很重要;您必须致电Truck
模型上的select
。这是因为当你调用where
方法时,你实际上返回了一个ActiveRelation
对象,这不是你在这里寻找的东西。
See ActiveRecord API for 'find_by' method
通用的解决方案使用 '存在?'方法
由于一些其他贡献者已经提到,exists?
方法专门设计用于检查是否存在某些东西。它不返回值,只是确认数据库有符合某些条件的记录。
如果您需要验证某些数据的唯一性或准确性,这很有用。好的部分是它允许你使用ActiveRelation(Record?) where(...)
标准。
举例来说,如果你有一个User
模型与email
属性,你需要检查的电子邮件中已经存在的分贝:
User.exists?(email: "[email protected]")
使用exists?
的好处是SQL查询运行是
SELECT 1 AS one FROM "users" WHERE "users"."email" = '[email protected]' LIMIT 1
比实际上返回数据更高效。
如果您需要实际有条件地从数据库检索数据,则不是使用的方法。但是,它对于简单的检查非常有用,并且语法非常清晰,所以其他开发人员完全知道你在做什么。使用适当的语法在多个开发人员的项目中非常重要写干净的代码,并让代码“评论”本身。
这是一个非常有用的演练,谢谢 –
在红宝石任何函数返回true或false,这是'truck_number_if_exists(ID)'你的情况,应该有问号到底 – ImranNaqvi
@ImranNaqvi:你是正确的,因为约定Ruby是将'?'追加到布尔方法;然而,在这种情况下,'truck_number_if_exist(id)'不是布尔方法;它返回一个值,如果存在,否则返回nil。由于它不是布尔方法,所以最终不应该使用'?'。 –
Rails有使用一个persisted?
方法 像你想轨
哪个版本是你吗? – Shaunak
看看是否存在?方法http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F – cristian