我正在使用范围和某些条件运行查询。像这样:
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 :(得分:10)
当然,请使用:
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
注意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
有关详细信息,请参阅#has_attribute。