Search code examples
ruby-on-railsrubyarraysruby-on-rails-3rails-geocoder

How to avoid bug if geocoder sends me empty array when retrieving country of user (Rails 4/geocoder)


I am building a daily deal Rails app

I am displaying to the user only the deals of the country i associate him with thanks to geocoder gem.

I wonder what would happen if geocoder fails (for any reason) to retrieve the country and sends an empty array, as i think it does when it fails to send ip( see https://github.com/alexreisner/geocoder#error-handling)

class StaticPagesController < ApplicationController

  def home    
    @deals = deal_in_user_country.featured_on_hp 
    respond_to do |format|
      format.html # home.html.erb
    end
  end

  # create a scope to filter the deals that meet the user's country
  def deal_in_user_country
    Deal.where(country: set_location_by_ip_lookup.country || 'United States') # if geocoder gets pb then default = US version
    end
  end 

end

As you see, I tried to use || and puts 'United States' but I don't think it will work. i think that if geocoder sends empty array , set_location_by_ip_lookup=[] and then set_location_by_ip_lookup.country will generate an error, am I right ?

How should i avoid bugs when geocoder sends an empty array ?

For info if it helps, here is how I set country in concerns/CountrySetter

module CountrySetter
  extend ActiveSupport::Concern

  included do
    before_filter :set_location_by_ip_lookup 
  end

  def set_location_by_ip_lookup  
    if Rails.env.development? or Rails.env.test?
      Geocoder.search(request.remote_ip).first
    else #in  production
      request.location
    end
  end
end

Solution

  • Your code should be fine, if geocoder allways returns at least an empty array (except I would not name this mehtod set_ because it's not setting anything)

    Try out on irb

    {a: [:d].first || :b}
    =>  {:a=>:d}
    
    {a: [].first || :b}
    => {:a=>:b}
    

    However i would put this in paranethesis to make it clear

    Deal.where(country: (set_location_by_ip_lookup.country || 'United States'))
    

    Gecodoer.search shouldn't be throwing exceptions, otherwise it would be named Geocoder.search! according to an unwritten ruby convention. I would double check this by plugin out the internet connection and see what happens