Skip to content

Instantly share code, notes, and snippets.

@dball
Created October 12, 2012 18:39
Show Gist options
  • Save dball/3880743 to your computer and use it in GitHub Desktop.
Save dball/3880743 to your computer and use it in GitHub Desktop.
Patch Geokit to work with SQL Server
module Geokit::ActsAsMappable::ClassMethods
# Distance is selected as an aliased expression, and we want to be able to
# use the alias in our order clause. SQL Server has no problem with that
# normally, but when the adapter rewrites the query in order to support
# pagination, it tries to use the alias. Unfortunately, the alias is invalid
# in the rewritten query; we need to use the expression.
#
# https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/198
#
# This extension overrides the order method on the relation to inline
# the expression when called with 'distance asc' or 'distance desc'.
#
# This patch may be rendered irrelevant if the SQL Server Adapter changes or
# makes more robust its offset with order support. It will break if
# geokit-rails3 stops storing the distance formula in an instance variable.
def geo_scope_with_inlined_distance_expression_in_order(*args)
arel = geo_scope_without_inlined_distance_expression_in_order(*args)
if @distance_formula
order_module = GeokitOrderByDistancePatch.
order_by_distance_formula_module(@distance_formula)
arel.extend(order_module)
end
arel
end
alias_method_chain :geo_scope, :inlined_distance_expression_in_order
end
module GeokitOrderByDistancePatch
def self.order_by_distance_formula_module(distance_formula)
Module.new do
define_method(:order) do |order|
if md = order.match(/^distance\s+(asc|desc)$/i)
order = GeokitOrderByDistancePatch.
order_by_distance_formula(distance_formula, md[1])
end
super(order)
end
end
end
def self.order_by_distance_formula(formula, direction)
distance = Arel::SqlLiteral.new(formula)
arel_order_class =
case direction
when 'asc' then Arel::Nodes::Ascending
when 'desc' then Arel::Nodes::Descending
else
raise ArgumentError("Invalid direction: #{direction}")
end
arel_order_class.new(distance)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment