2011-01-14 99 views
6

我正在使用範圍和一些條件運行查詢。事情是這樣的:向ActiveRecord查詢添加計算列

conditions[:offset] = (options[:page].to_i - 1) * PAGE_SIZE unless options[:page].blank?  
conditions[:limit] = options[:limit] ||= PAGE_SIZE 
scope = Promo.enabled.active 
results = scope.all conditions 

我想計算列添加到查詢(點時,我現在呼籲scope.all)。是這樣的:

(ACOS(至少(1,COS(0.71106459055501)* COS(-1.2915436464758)* COS(RADIANS(addresses.lat))* COS(RADIANS(addresses.lng))+ COS (0.71106459055501 )* SIN(-1.2915436464758)* COS(RADIANS(addresses.lat))* SIN(RADIANS(addresses.lng))+ SIN(0.71106459055501)* SIN(RADIANS(addresses.lat))))* 3963.19)as accurate_distance

有沒有辦法做到這一點,而不只是使用find_by_sql並重寫整個現有的查詢?

謝謝!

+0

您是否希望將此計算量添加到語句的SELECT部分​​,或者作爲條件的一部分?另外,數據庫是什麼? – bradheintz 2011-01-14 05:41:39

+0

作爲選擇語句的一部分 – rmw 2011-01-14 23:32:51

回答

9

當然,使用此:

conditions = Hash.new 
conditions[:select] = "#{Promo.quoted_table_name}.*, (ACOS(...)) AS accurate_distance") 
conditions[:offset] = (options[:page].to_i - 1) * PAGE_SIZE unless options[:page].blank?  
conditions[:limit] = options[:limit] ||= PAGE_SIZE 
scope = Promo.enabled.active 
results = scope.all conditions 

注意新:選擇 - 它告訴你的ActiveRecord要返回哪些列。結果中返回的對象將具有#accurante_distance訪問器。不幸的是,ActiveRecord是愚蠢的,將無法推斷出列的類型。您可以隨時添加方法:

class Promo 
    def accurate_distance 
    raise "Missing attribute" unless has_attribute?(:accurate_distance) 
    read_attribute(:accurate_distance).to_f # or instantiate a BigDecimal 
    end 
end 

有關詳細信息,請參閱#has_attribute