1

複数のコンテストとオブジェクトを設定しています。それらは、has_many:throughアレンジメントとcontest_objsで結び付けられています。コンテスト_objsにも投票があるので、いくつかのオブジェクトを含むいくつかのコンテストを開催できます。現在のランキングを計算するための複雑なSQL設定があります。ただし、ランキングのSQLselectステートメントでコンテストを指定する必要があります。私はこれを行うのに苦労しています。これは私がこれまでに得たものです:

@objects = @contest.objects.select('"contest_objs"."votes" AS v, name, "objects"."id" AS id, 
                                   (SELECT COUNT(DISTINCT "oi"."object_id")
                                           FROM  contest_objs oi
                                           WHERE ("oi"."votes") > ("contest_objs"."votes"))+1 AS vrank')

vrankの選択で、WHEREに「oi」も含まれるように指定する方法はありますか。 "contest_id" = @ contest.id?

4

3 に答える 3

3

@contest.id は整数であり、SQL インジェクションのリスクがないため、文字列補間を使用して次のことを行うことができます。

Model.select("..... WHERE id = #{@contest.id}")

別の可能な解決策は、ActiveRecord を使用してサブクエリを作成し、.to_sql を呼び出して生成された SQL を取得し、それをメイン クエリに挿入することです。

于 2012-08-28T22:19:40.767 に答える
2

sanitize_sql_array を使用します。

sanitize_sql_array('select ? from foo', 'bar')

モデルの外にいる場合、メソッドが保護されているため、これを行う必要があります。

ActiveRecord::Base.send(:sanitize_sql_array, ['select ? from foo', 'bar'])

http://apidock.com/rails/ActiveRecord/Sanitization/ClassMethods/sanitize_sql_array

于 2015-01-09T19:28:06.480 に答える
-1

次のように変数を sql コマンドに挿入できます。

Model.select("...... WHERE id = ?", @contest.id)

Rails が値をエスケープしてくれます。

編集:

コメントで Intrepidd が述べたように、これは機能しません。回答で提案したように、文字列補間を使用してください。これは、整数パラメーターに対して安全です。

クエリに複数の文字列を挿入していることに気付いた場合は、find_by_sql の使用を検討できます。これにより、上記の ? ただし、チェーンでは使用できないため、クエリ全体を書き直す必要があります。

于 2012-08-28T22:22:36.567 に答える