Adding a computed column to an ActiveRecord query

I run a query using the scope and some conditions. Something like that:

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 

I would like to add a calculated column to the query (the moment I now call scope.all). Something like that:

(ACOS (not less than (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 exact_distance

Is there a way to do this without using find_by_sql and rewriting the entire existing query?

Thanks!

+6
sql ruby-on-rails activerecord calculated-columns
source share
1 answer

Of course, use this:

 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 

Notice the new: select -, which tells ActiveRecord which columns you want to return. The returned object in the results will have the #accurante_distance accessory. Unfortunately, ActiveRecord is dumb and will not be able to infer the column type. You can always add a method:

 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 

See #has_attribute for more details.

+9
source share

All Articles