2011-09-21 47 views
2

我有一個名爲Invitation的模型,它具有一個名爲code的屬性。該應用程序的目標是通過輸入某處的代碼找到正確的邀請。即使查詢正確,Activerecord無法找到按屬性的模型

但是,我的問題是,即使輸入是正確的,ActiveRecord似乎無法在數據庫中查詢時發現任何結果。我創造了這個小測試來說明這個問題:

ruby-1.9.2-p290 :003 > code = Invitation.first.code 
Invitation Load (0.4ms) SELECT "invitations".* FROM "invitations" LIMIT 1 
=> "86f50776bf" 

所以在這一點上我在查詢的變量

ruby-1.9.2-p290 :004 > i = Invitation.where(:code => code) 
Invitation Load (0.2ms) SELECT "invitations".* FROM "invitations" WHERE "invitations"."code" = '86f50776bf' 
=> [] 

和響應加載這一邀請的代碼是一個空數組即使代碼直接來自數據庫。當使用code == Invitation.first.code來查看這些值是否相等時,它會返回true。我已經檢查過Ruby和數據庫的數據類型,它們都是Strings。

這是什麼原因造成的?我該如何解決這個問題?

+0

如果直接執行該SQL會發生什麼? – tadman

+0

同樣,雖然 - 我忘了提及 - 當我使用LIKE而不是=它找到它時。 – Marco

+0

要添加,這是首先生成「代碼」的代碼(在模型初始化時):'self.code = ActiveSupport :: SecureRandom.hex(5)if self.code.blank?'。之後我已經嘗試過to_s,但是這沒有效果。 – Marco

回答

1

我找到了解決辦法時,我偶然發現了this answer

在Ruby 1.9,現在所有字符串進行編碼。默認情況下,所有字符串應該是UTF-8,但是,SecureRandom.hex(30)返回ASCII-8BIT的編碼。

添加.force_encoding('UTF-8')向鍵的執行時,它解決了這個問題:)

1

根據您的評論,可能是列不是VARCHAR而是CHAR,或者它包含由ActiveRecord ORM層或數據庫驅動程序刪除的尾隨空格。 'foo''foo '是不相同的,但他們是LIKE足以匹配。

您可能希望該列切換到可變長度的,或者您的查詢調整測試:RTRIM(code)=?

+0

嗯,我用一個應用程序來檢查sqlite文件,但'code'字段是一個'VARCHAR',並沒有在行尾部空格,提示雖然 – Marco

+0

Woah,相當不錯的猜測。我從來沒有想過:) –

+0

'RTRIM()'版本是否工作? – tadman

0

@Marco,

你如何申報代碼變量?作爲字符串?

實施例:

code = "86f50776bf" 

code = '86f50776bf' 

+0

在上面的代碼中,我直接從另一個查詢('Invitation.first.code')的結果中分配它,並且在我正在分配的實際應用程序中它來自'session [:code]'變量。即使我直接將其分配給控制檯(主要使用雙引號),效果也不例外。 – Marco