檢查數據庫在處理之前是否會返回記錄的最有效方法是什麼?例如: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