Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing HTML5 geolocation data

How can I store and process the geolocation (long and lat) of a website user in Rails 3, so that it checks to see if we're already holding those details in a session for that user on every page request (if we're not holding the details, then we should request the user's location from the browser and then store those details in the session)?

like image 314
Elliot Avatar asked Mar 18 '12 12:03

Elliot


2 Answers

Based on your requirements I'd say that you don't actually need ajax, since most of the processing will be done using JS (to ask the user for access to their location, parse the response etc), I'd use JS to set a cookie, which Rails will then see).

In your controller

def action
  @lat_lng = cookies[:lat_lng].split("|")
end

In your view

<%- unless @lat_lng %>
<script>
  getGeoLocation();
</script>
<%- end %>

In one of your javascript files

function getGeoLocation() {
  navigator.geolocation.getCurrentPosition(setGeoCookie);
}

function setGeoCookie(position) {
  var cookie_val = position.coords.latitude + "|" + position.coords.longitude;
  document.cookie = "lat_lng=" + escape(cookie_val);
}

Note that none of the above tests to see if the user has a browser that supports geolocation, or if the user has granted (or denied) permission to use their location, and that the cookie will be a session cookie, and that the JS doesn't test to see if the cookie is already set. To set more complicated information on the cookie take a look at http://www.quirksmode.org/js/cookies.html For more information on GeoLocation using javascript see http://diveintohtml5.info/geolocation.html

like image 50
Chris Bailey Avatar answered Oct 06 '22 03:10

Chris Bailey


This is a very common pattern in Rails. In application_controller.rb or application_helper.rb (if you want it accessible from multiple controllers) define a method like

def lat_lng
  @lat_lng ||= session[:lat_lng] ||= get_geolocation_data_the_hard_way
end

The ||= bit reads "if the part on the left is nil, check the part on the right, and then assign the value to the part on the left for next time".

The @lat_lng here is an instance variable ... probably overkill for this case since I doubt getting the session data is any actual work, but since the browser will ask for permission, you really only want to do that once. And maybe the browser doesn't have a location-aware browser, so you'll need to fall back on something else, hence the call the method get_geolocation_data_the_hard_way which you'll have to write.

like image 43
Tom Harrison Avatar answered Oct 06 '22 03:10

Tom Harrison