将计算列添加到ActiveRecord查询

rmw*_*rmw 6 sql activerecord ruby-on-rails calculated-columns

我正在使用范围和一些条件运行查询.像这样的东西:

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 
Run Code Online (Sandbox Code Playgroud)

我想在查询中添加一个计算列(当我现在调用scope.all时).像这样的东西:

(ACOS(至少(1,COS(0.71106459055501)*COS(-1.2915436464758)*COS(RADIANS(addresses.lat))*COS(RADIANS(地址.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并重写整个现有查询的情况下做到这一点?

谢谢!

Fra*_*eil 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 
Run Code Online (Sandbox Code Playgroud)

注意new: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
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅#has_attribute.

  • 因为这是在2011年想知道这仍然是在Rails4中这样做的首选方式吗? (4认同)