2011-01-14 2 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

+0

select 서술문의 일부로 – rmw

답변

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 

주 새로운 : 선택 - 당신이 반환 원하는 열 액티브을 알 수있다. 결과에서 반환 된 객체에는 #accurante_distance 접근자가 있습니다. 안타깝게도 ActiveRecord는 벙어리 (dumb) 상태이므로 열 유형을 추론 할 수 없습니다.

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를 참조하십시오 : 당신은 항상 방법을 추가 할 수 있습니다.

+1

has_attribute 링크에서 "read_attribute"에 대해 투표하십시오 – Naveed

+3

이것이 2011 년에 궁금해 졌기 때문에 Rails4에서 이것을 여전히 선호하는 방법입니까? – codeObserver