2012-06-12 51 views
0

我在我的Rails應用程序中設置了一個命名範圍,該範圍用於通過其ID(直接來自索引視圖)或UUID(來自電子郵件 - 基本上只是爲了讓用戶可以「T在任何輸入ID和瀏覽記錄)Rails find_by with OR

scope :by_uuid, lambda { |id| where('id = ? OR uuid = ?', id, id) } 

這在表演動作用,所以ID來自網址,例如

services/114 

services/74c083c0-8c29-012f-1c87-005056b42f8a 

這個偉大的工程,直到你得到一個UUID如74c083c0-8c29-012f-1c87-005056b42f8a 這樣,不幸的是,轉換爲int值爲a nd我們得到的服務/ 74以及正確的UUID記錄

向範圍添加一個.first將無濟於事,因爲每個記錄的順序可能不同,因此不起作用。

有沒有辦法來防止軌道轉換這樣的ID和字面上的字符串?很顯然,不會有一個ID與之相匹配的記錄,但如果它傳遞給它的字符串的整數值不變,我們可以返回任何東西。

使用動態查找,如按預期

Service.find_by_uuid 

Service.find_by_id 

工作,但是我們需要能夠使用UUID或同一方法ID檢索記錄(顯示)。

有沒有辦法做這樣的事情

Service.find_by_id_or_uuid 
+2

您最初的想法使用帶有lambda函數的命名範圍應該工作。你確定你在代碼中沒有錯誤嗎?它似乎應該是作用域:by_uuid,lambda {where('id =?或uuid =?',id,uuid)} - 您的問題中的參數化查詢中有兩個參數。 –

+0

是的,因爲id是來自URL字符串 - 所以我們可以有服務/ 114或服務/ 74c083c0-8c29-012f-1c87-005056b42f8a,它需要對兩者作出響應,實際上我忽略了| id |宣言。我編輯了上面的帖子來澄清。問題在於它獲取UUID字符串的int值並拉起服務/ 74而不是正確的記錄。 – Oranges13

回答

1

我們固定了以下更改範圍這個問題:

scope :by_uuid, lambda { |id| where('binary id = ? OR uuid = ?', id, id) } 

這確保了ID字符串採取的是它的二進制值而不是被轉換成int。但是,這將只能使用基於MYSQL的應用程序