2016-06-14 48 views
1

我遇到問題。早些時候,我發佈了一個類似的問題,我將要問哪個已經回答,可以在這裏找到相關背景ActiveRecord Count and SQL count do not match由於未知的OID被視爲字符串,ActiveRecord和SQL未返回相同結果的情況字符串

這個問題與計算查詢結果有關。在這個問題中,我沒有得到相同的計數結果,而是得到了不同的對象結果。

這裏是ActiveRecord的代碼:

scope :unverified_with_no_associations, -> { 
    find_by_sql("SELECT DISTINCT(accounts.id, accounts.email) FROM accounts WHERE level = 0 AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM verifications) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM positions) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM edits) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM posts) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM reviews) AND id NOT IN 
       (SELECT DISTINCT(sender_id) FROM kudos) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM stacks WHERE account_id IS NOT NULL)") 

這將返回[#<Account:0x007f96bf143c70 id: >]和我的SQL輸出後,得到這個消息unknown OID 2249: failed to recognize type of 'row'. It will be treated as String.

如果我在數據庫中運行上面的SQL代碼,我找回我需要什麼:

-------row------- 
(1234,[email protected]) 

什麼原因導致這種不匹配,我該如何避免它。我發現這篇文章關於自定義postgres類型Custom postgres types,但這看起來像我需要到事情的本質,我想避免這種情況。有人知道爲什麼這是一個問題嗎?

回答

1

你得到了這個問題,因爲ActiveRecord無法將這一行識別爲您帳戶表中的行。 AR不解析你的sql,它不知道如何處理匿名cortage。

如果使用find_by_sql您選定的屬性不會映射到您的模型正確,但仍然可以訪問,那麼嘗試:

result.id 
result.email 

但你也有兩種方法來解決這個問題。

首先(這是非常的hackish,但簡單的解決方案),將您的SQL來Arel,即vaild的範圍:

scope :unverified_with_no_associations, -> { 
    send(:default_scoped).from(Arel.sql("(SELECT * FROM accounts WHERE level = 0 AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM verifications) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM positions) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM edits) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM posts) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM reviews) AND id NOT IN 
       (SELECT DISTINCT(sender_id) FROM kudos) AND id NOT IN 
       (SELECT DISTINCT(account_id) FROM stacks WHERE account_id IS NOT NULL)) 
       AS accounts")) 

...並調用AR不同方法:

Account.unverified_with_no_associations.select(:id, :email).distinct 

(這是更好的解決方案):

不要使用sql di rectly。用Arel(​​)或squeelhttps://github.com/activerecord-hackery/squeel

+0

重寫您的範圍感謝rootatdarkstar。阿雷爾做到了。 –

相關問題