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')
データベースは、数値から文字列を減算しようとしているのを見て喜んでいる場合とそうでない場合があるため、意味を正確に伝え、自分で型変換を行うことが最善です。