Search code examples
ruby-on-railsthinking-sphinx

undefined local variable or method `zip_codes'


After trying to change the search to pull locations from the zip code and not the location_id the results return empty.

I had the code previously working when I used location ids. Does someone know how I can get it to work with the zip codes? I have a zip_code column in the Users table and zipcode column in the Locations table.

The location_id being used a auto increment from each row in the Locations table.

Current code:

def index
    if location = Location.find_by_zipcode(params[:search])
        latitude  = location.latitude * Math::PI / 180 
        longitude = location.longitude * Math::PI / 180 

        zip_codes = Location.search_for_ids( 
          :geo   => [latitude, longitude], 
          :with  => {:geodist => 0.0..400_000.0}, 
          :order => 'geodist ASC',
          :per_page => 1_000
        ) 
        @users = User.where(:zip_code => zip_codes)  

Code that works with location_id:

  def index
    if location = Location.find_by_zipcode(params[:search])
        latitude  = location.latitude * Math::PI / 180 
        longitude = location.longitude * Math::PI / 180 

        location_ids = Location.search_for_ids( 
          :geo   => [latitude, longitude], 
          :with  => {:geodist => 0.0..400_000.0}, 
          :order => 'geodist ASC',
          :per_page => 1_000
        ) 
        @users = User.where(:location_id => location_ids)  

Tables

Location:
      t.string :zipcode
      t.string :city
      t.string :state
      t.float :latitude
      t.float :longitude


      User:
      t.string :email
      t.string :password_digest
      t.string :zip_code
      t.string :location_id
      t.string :time_zone
      t.string :birthday
      t.string :name
      t.string :username

The location id was a auto increment.


Solution

  • Side Note: The original version of this answer was posted before we determined that thinking-sphinx was being used, so it is important to note that I have never used this gem / library, and can only offer my best estimated guess based on the documentation.

    The error message is saying you don't have a method or variable called zip_codes, which from what we can see in the code, is correct (it is most definitely not defined anywhere).

    If I am correct that thinking-sphinx returns an array of Active Record objects (or something similar), then I believe you should be able to use most of this code (using the pluck method below).

    Rather than using the search_for_ids method, which I believe only returns a collection of database row ids, we'll use the normal search method. As my understanding goes, what is returned from the search method is a collection of fully populated active record objects. I believe your location search will look like this:

    locations = Location.search
          :geo   => [latitude, longitude], 
          :with  => {:geodist => 0.0..400_000.0}, 
          :order => 'geodist ASC',
          :per_page => 1_000
    

    You should be safe, at that point, to extract only the zipcode fields from that collection, like so:

    User.where(zip_code: locations.pluck(:zipcode))
    

    If the pluck method does not exist for that collection, you may need to try the same procedure with the map method instead:

    locations.map(&:zipcode)
    

    Or a more explicit version:

    locations.map{|location| location.zipcode}
    

    The reason why your attempt to do .where(:zip_code => zip_codes) after renaming the variable is because (most likely) your zip_codes (previously named location_zips) is an array of objects, not a collection of zipcodes as you expected. Admittedly, this is an assumption because I do not know what this search_by_zipcode method does, but this seems like a reasonable explanation based on the behaviour you described.