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)?
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With