0
votes

Trying to figure out how to display a map in my rails 4 app show page.

I have a model called addresses. This is the address.rb file:

class Address < ActiveRecord::Base

  geocoded_by :full_address   # can also be an IP address
  before_save :capitalise_address
  before_save :upcase_zip


  # --------------- associations

  belongs_to :addressable, :polymorphic => true

  # --------------- scopes

  # --------------- validations

  validates_presence_of :unit, :street, :zip, :country 

  # --------------- class methods

  def first_line
    [unit, street].join(' ')
  end

  def middle_line
    if self.building.present? 
    end
  end

  def last_line
    [city, region, zip].join('   ')
  end

  def country_name
    self.country = ISO3166::Country[country]
    country.translations[I18n.locale.to_s] || country.name
  end

  def address_without_country
    [self.first_line, middle_line, last_line].compact.join(" ")
  end

  def full_address
    [self.first_line, middle_line, last_line, country_name.upcase].compact.join("\n")
  end


  # --------------- callbacks

  # after_validation :geocode, if  self.full_address.changed? 

  # --------------- instance methods

  # --------------- private methods

  protected

    def upcase_zip
      zip.upcase
    end

    def capitalise_address
      ["building", "street", "city", "region", "country" ].each do | name |
        self.attributes[name] = self.attributes[name].capitalize
      end
    end

end

I have added geocoded, gmap4rails, underscore gems to my gem file.

In my addresses controller I have:

class AddressesController < ApplicationController
  before_action :set_address, only: [:show, :edit, :update, :destroy]
  respond_to :html, :xml, :json

  def index
    @addresses = Address.all
    respond_with(@addresses)
  end



  def show
    respond_with(@address)
  end

  def new
    @address = Address.new
    respond_with(@address)
  end

  def edit
  end

  def create
    @address = Address.new(address_params)
    @address.save
    respond_with(@address)
  end

  def update
    @address.update(address_params)
    respond_with(@address)
  end

  def destroy
    @address.destroy
    respond_with(@address)
  end

  private
    def set_address
      @address = Address.find(params[:id])
    end

    def address_params
      params[:address].permit(:unit, :building, :street, :city, :region, :zip, :country)

    end
end

In my address show page I have:

<script src="//maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=geometry" type="text/javascript"></script>
<script src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js" type="text/javascript"></script>

<div class="containerfluid">
    <div class="row">
        <div class="col-md-12">

                <div style='width: 800px;'>
                     <div id="map" style='width: 800px; height: 400px;'>

                     </div>
                </div>
                <div class="addressbacking"> 
                    <%=  @address.full_address %>
                    <div style='width: 800px;'>
  <div id="one_marker" style='width: 800px; height: 400px; z-index:1'></div>
</div>
                </div>
            </div>
        </div>
    </div>
</div>

<script type="text/javascript">
    handler = Gmaps.build('Google');
    handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
        markers = handler.addMarkers(<%=raw @hash.to_json %>);
        handler.bounds.extendWith(markers);
        handler.fitMapToBounds();
    });
</script>

I am trying to follow this set up tutorial, which suggests adding this to my controller:

  def index
    @users = User.all
    @hash = Gmaps4rails.build_markers(@users) do |user, marker|
      marker.lat user.latitude
      marker.lng user.longitude
      marker.title user.title
    end
  end

Which I do (although I don't know what it means or if its the cause of my problem), so that my index action in the controller is:

  def index
    @addresses = Address.all
    respond_with(@addresses)
    @hash = Gmaps4rails.build_markers(@users) do |user, marker|
      marker.lat user.latitude
      marker.lng user.longitude
      marker.title user.title
    end

  end

I have a form partial in my views which has input elements for each of the strong params showing at the bottom of my controller.

When I try this, a map renders, but its not the address that i entered in my form.

How do I fix this? I don't have longitude and latitude attributes in my address table.

2
Have you tried looking at the browser console? Any notable errors? Also you should use the var keyword in your javascript! - max
where should I put var? new to js - Mel
When defining variables (var x = 1;). If you don't use var you are implicitly creating a global. If you are starting out with javascript try using strict mode by adding "use strict"; at the top of the file / script tag. It will warn you about this any many other rookie mistakes. - max
I'm going to have to do some googling to try to understand. where does var go? where does use strict go? does it matter that this is a view page rather than a js file? - Mel
"use strict"; goes on the top of the file, script tag or function. Its pretty new so you won't find it in older tutorials. It tells the javascript interpreter to warn about common misstakes and parts of the language that are broken. - max

2 Answers

0
votes

You geocoded class Address, so it has latitude and longitude method. Was User class geocoded too?

def index
  @addresses = Address.all
  @hash = Gmaps4rails.build_markers(@addresses) do |address, marker|
    marker.lat address.latitude
    marker.lng address.longitude
  end
end

Be sure to add params to addresses:

class AddLatitudeAndLongitudeToAddress < ActiveRecord::Migration
  def change
    add_column :addresses, :latitude, :float
    add_column :addresses, :longitude, :float
  end
end
0
votes

Let's check app/assets/javascripts/addresses.coffee For example:

class RichMarkerBuilder extends Gmaps.Google.Builders.Marker
  create_marker: ->
    options = _.extend @marker_options(), @rich_marker_options()
    @serviceObject = new RichMarker options 
  rich_marker_options: ->
    marker = document.createElement("div")
    marker.setAttribute 'class', 'marker_container'
    marker.innerHTML = @args.marker
    { content: marker }

handler = Gmaps.build 'Google', { builders: { Marker: RichMarkerBuilder} } 
handler.buildMap { provider: {}, internal: {id: 'map'} }, ->
  markers = handler.addMarkers([
    {"lat": 0, "lng": 0, 'marker': '<span>Here!</span>'}
  ])
handler.bounds.extendWith(markers)
handler.fitMapToBounds()

In your model add

 geocoded_by :full_address
 after_validation :geocode