Tuesday, August 26, 2008

Geokit: Oddities

1. When using Geokit + Google, sometimes, giving a valid postal code will fail. It's a very random thing. I'm not sure if it's just Google, but sometimes, it fails, even with a valid postal code. I'm guessing it has something to do with the network or perhaps they limit how many you can ask for in a period of time so you don't overload their server.

2. If you add :within to your find, Geokit doesn't recognize that :within => nil means not to add :within. Sometimes, you have a variable that may or may not be nil, and this controls whether you want to search using a distance. The :origin key works fine with nil, but :within does not. It blindly adds the distance calculations to the find. I had to hack acts_as_mappable.rb a little bit in order to get it to work.

In the apply_distance_scope(options) function, I have:

distance_condition = "#{distance_column_name} <= #{options[:within]}" if options.has_key?(:within) && !options[:within].nil?
distance_condition = "#{distance_column_name} > #{options[:beyond]}" if options.has_key?(:beyond) && !options[:beyond].nil?

and

[:within, :beyond, :range].each { |option| options.delete(option) }

This will take the :within => nil into account and skip the adding of the distance calculations out of the find and remove the useless keys.

3. In the Geokit README, there is a section about using :includes. However, there isn't a section on using :joins. Apparently, when you use :joins, things can screw up. For instance, if I have

Shop.find(:joins => "INNER JOIN products where products.shop_id = shops.id", :conditions => ..., :origin => ..., :within => ...)

You would expect a Shop object to be returned. This is true, but I found a small error. The Product id replaced the Shop id, leaving me with a Shop object with an id of the Product id.

I traced this down to the function add_distance_to_select(...). In this function, it blindly sets the :select option in the find to "*" if it isn't already defined. I'm guessing, because both Shop and Product have ids, they get mixed up somehow.

In order to fix this, I needed to add :select => "shops.*".

Hopefully, this info helps those that are having the same problems. If you have a better solution, feel free to share!


W