Добавление вычисляемого столбца в запрос 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 (address.lat)) * COS (RADIANS (address.lng)) + COS (0,71106459055501) * SIN (-1.2915436464758) * COS (RADIANS (address.lat)) * SIN (RADIANS (address.lng)) + SIN (0.71106459055501) * SIN (RADIANS (address.lat)))) * * 3963.19) в качестве точного расстояния
Есть ли способ сделать это без использования find_by_sql и переписывания всего существующего запроса?
Спасибо!
1 ответ
Конечно, используйте это:
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 для деталей.