0

Ruby on Rails チュートリアルの著者は、テキスト内のエラーの報告を喜んで受け取ると述べていますが、すぐに、エラーがあるとは思っていないので、直接報告しないでくださいと述べています。それでも、そのようなエラーを見つけた可能性があると思います。チュートリアルのバージョン 3.2 のコード リスト 11.44 では、次のメソッドが定義されています。

  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

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

作成者がこのフォーラムでチュートリアルのバグ レポートを監視している場合は、これが本当にバグであるかどうかを確認する応答を得て、おそらく修正してもらうとよいでしょう。:-)

ありがとう!

[PS: 著者は、「ru​​by-on-rails」および「tutorials」タグを使用して、ここでバグを報告するよう読者に指示していますが、SO は「tutorials」タグの使用を許可していません。]

4

1 に答える 1

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

これは、配列のサイズに依存する多くの s を持つクエリを構築し、user_id = ? ORpostgreSQL が喜んで対応できる int を渡します。

于 2012-04-25T23:02:37.793 に答える