Created
October 12, 2012 18:39
-
-
Save dball/3880743 to your computer and use it in GitHub Desktop.
Patch Geokit to work with SQL Server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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