Search code examples
ruby-on-railsrubyrails-geocoder

Adding an instance variable using enumerable#map returns wrong information


I'm currently working on a Rails/Mapbox app. I currently am not storing geolocation for my House object, and rather am using a helper method to create a temporary instance variable to store geolocation to pass to Mapbox.

Below, all_houses argument is an array of many House objects.

I created the following helper method:

def add_geolocation(all_houses)
  all_houses.map do |house|
    house_geo = find_geolocation(house.address)

    class << house
      attr_accessor :geo
    end

    house.geo = house_geo
  end
end

I'm using the Gon Gem to pass this information from my controller to Mapbox. What is being returned is an array of arrays with only geolocations stored for each house. What I am trying to do is pass every instance variable stored for the each House object and also pass its geolocation.

Also, to add, I have also tried the Ruby method Object#set_instance_variable and I am getting the same result.

What I want:

[<House:0x007fe5670d9cc0 @a="a", @b="b", @geo=[10, 10]>, <House:0x007fe5670d9cc0 @a="a", @b="b", @geo=[10, 11]>, <House:0x007fe5670d9cc0 @a="a", @b="b", @geo=[12, -12]>, ...]

What I am getting is an Array of Arrays with only geolocations, for example:

[[10, 10], [10, 11], [12, -12] ...]

Edit:

Below is what I have in my controller. gon is from the Gon Gem

def index
  @houses = House.all
  json_houses = add_geolocation(House.all)

  gon.houses = json_houses
end

Solution

  • When using map, the last line of the block is the implicit return statement from which the new array is constructed. To return the modified house objects, house needs to be the return

    def add_geolocation(all_houses)
      all_houses.map do |house|
        house_geo = find_geolocation(house.address)
    
        class << house
          attr_accessor :geo
        end
    
        house.geo = house_geo
        house
      end
    end
    

    Edit: You may need something like this in your controller method

    def index
      @houses = House.all
      json_houses = add_geolocation(House.all)
    
      gon.houses = json_houses.as_json(methods: %i(geo))
    end