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')
Ваша база данных может или не может быть счастлив видеть, что вы пытаетесь вычесть строку из числа так оно лучше всего сказать, что вы имеете в виду и сделать преобразование типа самостоятельно.
Согласно [этому Rails API] (http://api.rubyonrails.org/classes/ActiveRecord/Base.html) второй способ, которым вы написали *, - это безопасный путь. Что с этим не получилось? – MrDanA
Второй способ не работает, поскольку он ожидает имена столбцов, когда видит массив. Этот синтаксис работает только тогда, когда() и: conditions => –
При использовании функций sql строители рельсов начинают разрушаться. Возможно, вам стоит взглянуть на Squeel, который лучше поддерживает функции sql: https://github.com/ernie/squeel (или railscast: http://railscasts.com/episodes/354-squeel) – DGM