2016-06-14 1 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コードを実行した場合、私は私が必要なものを取得するSQL出力unknown OID 2249: failed to recognize type of 'row'. It will be treated as String.

後にこのメッセージが表示されます:

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

このミスマッチの原因は何か、どのように避けることができますか。私はカスタムpostgresタイプCustom postgres typesについてこのポストを見つけましたが、これは私が物事のぎこちなさに到達する必要があるように見えます、そして、私はこれを避けたいと思います。誰かがなぜこれが問題であるかを知っていますか?

答えて

1

ActiveRecordはこの行をアカウントテーブルの行として認識できないため、この問題が発生します。 ARはあなたのSQLを解析していないので、匿名のコルテージをどうするか分からない。

あなたがfind_by_sqlを使用している場合は、あなたの選択が正しくお使いのモデルにマッピングされたが、まだアクセス可能なので、試してみて属性:

result.id 
result.email 

をしかし、あなたはまた、その問題を解決するには、2つの方法があります。

まず(それは非常にハックが、簡単なソリューションです)、ArelにあなたのSQLを変換し、スコープのことが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を使用しないでください直腸にスコープをArel(​​)またはsqueelhttps://github.com/activerecord-hackery/squeel

+0

と書き直してください。rootatdarkstarありがとうございます。 Arelはトリックをしました。 –

関連する問題