Rails はsanitize_sql_for_conditions、プレースホルダーを処理するために内部的に使用します。もちろん、そのメソッドは保護されているため、ActiveRecord モデルの外で (クリーンに) 使用することはできません。次を使用して保護を回避できますsend。
nearest = Site.minimum(
Site.send(:sanitize_sql_for_conditions, [
'abs(latitude - ?) - abs(longitude - ?)',
params[:lat].to_f, params[:lon].to_f
]
)
または、そのロジックをSiteクラスメソッド内に配置して、sanitize_sql_for_conditionsトリックなしで使用できるようにすることもできます。
class Site < ActiveRecord::Base
def self.whatever_this_is(lat, lon)
minimum(
sanitize_sql([
'abs(latitude - ?) - abs(longitude - ?)',
lat, lon
])
)
end
end
そして、コントローラーで:
nearest = Site.whatever_this_is(params[:lat].to_f, params[:lon].to_f)
to_f呼び出しに注意してください。params[:lat]それらを含めない場合は、params[:lon]文字列になり、sanitize_sql_for_conditionsそのように引用されます。
abs(latitude - '11.23') - abs(longitude - '42.6')
データベースは、数値から文字列を減算しようとしているのを見て喜んでいる場合とそうでない場合があるため、意味を正確に伝え、自分で型変換を行うことが最善です。