Using Geokit with Searchlogic

For those of you that don’t know, geokit is a great little gem that allows you to geocode addresses. It adds in very easy to use options in the ActiveRecord find method. Ex:

# will return all venues within 10 miles of the 10018 zip code
Venue.find(:all, :origin => "10018", :within => 10)

The problem is that you can’t use geokit options in a named scope. Since searchlogic is named scope driven this presented a problem. So I wrote a little module that transfers geokit options from named scopes to the actual arguments of the method:

module GeokitForNamedScopes
  OPTIONS = [:origin, :within, :beyond, :range, :formula, :bounds]

  def find(*args)
    super(*transfer_from_scope_to_args(args))
  end

  def count(*args)
    super(*transfer_from_scope_to_args(args))
  end

  private
    def transfer_from_scope_to_args(args)
      find_options = scope(:find)
      if find_options.is_a?(Hash)
        options = args.extract_options!
        OPTIONS.each do |key|
          options[key] = find_options.delete(key) if find_options.key?(key)
        end
        args << options
      else
        args
      end
    end
end

class ActiveRecord::Base
  class << self
    def acts_as_mappable(*args)
      result = super(*args)
      extend GeokitForNamedScopes

      GeokitForNamedScopes::OPTIONS.each do |key|
        named_scope key, lambda { |value| {key => value} }
      end

      result
    end

    VALID_FIND_OPTIONS += GeokitForNamedScopes::OPTIONS
  end
end

It’s far from perfect. The glaring problem is obviously redefining the VALID_FIND_OPTIONS constant, which throws a warning. But it works and it’s good enough for now. If anyone has any suggestions on how to improve this I’d to hear them. But you should be able to use geokit options in a named_scope with the above code. Ex:

Venue.origin("10017").within(10).all # => will return all venues within 10 miles of 10017

Using this through associations

Geokit doesn’t really support making these calls through associations. But if you read the documentation. You will notice they do support this:

acts_as_mappable :through => :whatever

You can use that feature to bridge the gap

Hopefully this helps some of you.

  • Share/Save/Bookmark


4 Responses to “Using Geokit with Searchlogic”

  1. Nimesh says:

    Hello Ben,

    Great stuff. But can you please explain me where to insert this module. I tried inserting it in /lib directory, but it did not work for me. Thanks in advance!!!

  2. [...] Using Geokit with Searchlogic – Binary Logic [...]