向ActiveRecord查询添加计算列

7

我正在使用作用域和一些条件来运行查询。就像这样:

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(least(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并重写整个现有查询?
谢谢!

你是想将这个计算出来的量添加到SELECT语句中,还是作为条件的一部分?另外,数据库是什么? - bradheintz
作为选择语句的一部分 - rmw
1个回答

11

当然,可以使用这个:

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 

注意新的 :select - 它告诉 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


7
这是2011年的做法,不知道在Rails4中是否仍然是首选方法? - codeObserver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接