레일즈는 내부적으로 자리 표시자를 처리하기 위해 sanitize_sql_for_conditions
을 사용합니다. 물론,이 메소드는 보호되어 있으므로 ActiveRecord 모델 외부에서 (깔끔하게) 사용할 수는 없습니다.
nearest = Site.minimum(
Site.send(:sanitize_sql_for_conditions, [
'abs(latitude - ?) - abs(longitude - ?)',
params[:lat].to_f, params[:lon].to_f
]
)
아니면 속임수없이 sanitize_sql_for_conditions
를 사용하도록 허용 할 것 그래서 당신은 Site
클래스 메소드 내에서 그 논리를 넣을 수 있습니다 : 당신은 send
를 사용하여 protectedness 주위에 얻을 수에 다음
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
두 번째 방법은 배열을 볼 때 열 이름을 필요로하기 때문에 작동하지 않습니다. 이 구문은 when() 및 : conditions => –
에서만 작동합니다. SQL 함수를 사용하면 레일 빌더가 고장납니다. Squeel은 SQL 함수를보다 잘 지원합니다 : https://github.com/ernie/squeel (또는 railscast : http://railscasts.com/episodes/354-squeel) – DGM