2012-04-25 13 views
0

Ruby on Railsチュートリアルの著者は、テキスト内のエラーの報告を受けて喜んでいると言いますが、すぐに彼は実際に何かがあるとは思わないと言いますので、直接彼に報告しないでください。それにもかかわらず、私はそのような誤りを発見したかもしれないと信じています。以下のメソッドが定義されているチュートリアルの3.2バージョンの11.44コードリストに:Ruby on Rails 3.2チュートリアルの第11章でのSQL補間のバグ?

def self.from_users_followed_by(user) 
    followed_user_ids = user.followed_user_ids.join(', ') 
    where("user_id IN (?) OR user_id = ?", followed_user_ids, user) 
    end 

の方法の最初の行は、(参加する呼び出しの文字列を生成します)。 2番目の行は、その文字列をSQL WHERE句のIN部分のカッコ内のプレースホルダに挿入します。私はこれをデフォルトのSQLiteドライバでテストしていません。なぜなら、高度な演習のための作者の指示に従っていて、テストと開発環境のためにPostgreSQLに切り替えたからです。 PostgreSQLドライバでは、プレースホルダ置換メカニズムは、そのプレースホルダの置換変数が文字列値であることを検出し、SQLが文字列値に期待する周囲の一重引用符で値を挿入します。その結果、WHERE節は "WHERE user_id IN ('...') OR ..."となります。 user_id列はINT列なので、これは拒否されます(少なくともPostgreSQLでは)。この問題は後で、サブクエリを使用してメソッドのバリアント実装によってテキスト内で取り除かれますが、著者は明示的に、上に引用した失敗したコードを追加した後、テストスイート内のすべてのバリデーションを渡す必要があります。

このフォーラムでは、このフォーラムでこのバグレポートを監視している場合は、これが実際にバグかどうかを確認し、おそらくそれを修正したという応答を得るのは良いことです。 :-)

ありがとう!

[PS:著者は、タグ「ルビーオンレール」と「チュートリアル」を使用して、ここにバグを報告するために読者を指示したがSO「チュートリアル」タグの使用を許可していません。]

+0

私の解決策があなたのために働いているかどうか教えてください。有用であれば、それをチェックしてください。それは* SOのポイントです。 – Jonathan

答えて

0

へあなたが使用することができ、この問題を回避:

def self.from_users_followed_by(user) 
    followed_user_ids = user.followed_user_ids 
    where((['user_id = ?'] * followed_user_ids.size).join(' OR '), *followed_user_ids) 
    end 

これは、配列のサイズに依存user_id = ? ORの多くでクエリを作成し、PostgreSQLが対応に満足しなければならないことをint型に渡します。

+0

あなたの投稿をありがとう。しかし、自分のオペレーションで指摘したように、私は本当にバグの回避策を探しているわけではありません(このチュートリアル自体はバグを避けるサブクエリを使用するより良いアプローチを提供します)。私がしてきたのは、チュートリアルの作者にバグがあることを知らせる方法です。修正することができます。私の後に来る読者は、私が何を壊れた。 –

+0

バグが修正された場合はあなたの質問が解決され、それが問題なのかどうかは正しいか間違った回答があり、それらの回答は投票または選択されます。ちょうどこの場所はSEOの慈善団体ではなく、ここに掲示するためのアドバイスは理由のために行われました。あなたは反ガイドラインであるという良い質問に私のアップヴォートを失った – Jonathan

関連する問題