Calculating distance using geo coordinates in ruby

As the social part of the sites is growing stronger, everyone of us has to
include a user’s location of some sort into the application. There can be many
reasons for that, be it location based search, advertising or something else
unrelated. But mark this, you will have to deal with locations in the future.

I won’t get into the details of how to get the user’s latitude and longitude,
but geocoder gem could be helpful for you.

I have found one JavaScript solution with the descriptions of what are the
different implementations of the calculation and which one is more correct so
I won’t get into the explanation. You can check the explanation and even more
stuff you can do with 2 geo coordinates on the Movable Type Scripts

The distance can be calculated using 3 formulas, Haversine, Spherical
Law of Cosines
, and Equirectangular approximation

The prerequisites we will need are degree to radian conversion which is easily
done with degree / 180 * Math::PI but to make the code easier to write we
can monkey patch the Float with to_rad method which will calculate this for
us. We could use refinements, or make a method object and not pollute the
global space but we can leave it like this for now.

class Float
  def to_rad
    self / 180 * Math::PI

After we have done the prerequisites let’s assume that we have two objects,
and each one has a latitude and a longitude. For the sake of this post we can
make them a hash with two keys latitude and longitude. And we take the
earth radius as 6371km

class Geodistance
  include Math
  attr_reader :from, :to, :lat1, :lon1, :lat2, :lon2
  RADIUS = 6371
  def initialize(from, to)
    @from = from
    @to = to
  def distance(type = 'haversine')
      raise NotImplementedError, 'The type you have requested is not implemented, try "cosines" or "approximation", or without params for "haversine"'
  def haversine
    d_lat = (from[:latitude] - to[:latitude]).to_rad
    d_lon = (from[:longitude] - to[:longitude]).to_rad
    a = sin(d_lat / 2) * sin(d_lat / 2) + sin(d_lon / 2) *
      sin(d_lon / 2) * cos(lat1) * cos(lat2)
    c = 2 * atan2(sqrt(a), sqrt(1-a))
    RADIUS * c
  def cosines
    acos(sin(lat1) * sin(lat2) +
         cos(lat1) * cos(lat2) *
         cos(lon2 - lon1)) * RADIUS
  def approximation
    x = (lon2 - lon1) * cos((lat1 + lat2) / 2)
    y = lat2 - lat1
    sqrt(x * x + y * y) * RADIUS
  def set_variables
    @lat1 = from[:latitude].to_rad
    @lat2 = to[:latitude].to_rad
    @lon1 = from[:longitude].to_rad
    @lon2 = to[:longitude].to_rad

As you can see by calling the distance method with all 3 parameters, each one
will produce a slightly different result. As they say, the haversine one
should be the most accurate, but take caution. I would like to benchmark them
some day and see which one calculates the result faster.

Thanks to Movable Type Scripts for providing the JavaScript
code and all the insight. I just did a rewrite in Ruby.

Will Paginate in Rails using remote request

Have you ever wondered why is there no remote option for will_paginate gem? It’s too complex and data dependent to handle all possible situations. I have made a workaround that can help you implement simple ajax pagination for your rails application. I will be replacing the whole yield part here, but you can customize it whatever way you like.

Step 1. Extract your required view into a partial so you have

<!-- app/views/posts/index.html.erb -->
< %= render "index" %>


<!-- app/views/posts/_index.html.erb -->
<h1>Listing posts</h1>
<table id="posts">
 < %= render partial: 'post', collection: @posts %>
< %= will_paginate @posts, remote: true %>
<br />
< %= link_to 'New Post', new_post_path, remote: true %>

Note the remote: true part of the will_paginate call, we will bind the javascript to it in an instance.

2. Add a div surrounding your yield tag in your layout

<!-- app/views/layouts/application.html.erb -->
<div id="content>
  < %= yield %>

3. Create index.js.erb which will replace the contents of the div with paged table data.

// app/views/posts/index.js.erb
$("div#content").html('< %= escape_javascript(render "index") %>');

4. Bind the will_paginate link click to the rails remote call using coffeescript in

# app/assets/javascripts/
$('.pagination[remote=true] a').live 'click', ->
  window.history.pushState(null, 'hi', $(this).attr("href"))
  return false

We also change the address in the navigation bar with PushState, because it can happen someone will press F5 or something and reload with a different params[:page].

Update: As my coworker Oliver mentioned, i forgot to include responding to js in our controller for the index action

def index
  @posts = Post.paginate(per_page: 8, page: params[:page]
  respond_to do |format|

Installing Rails Server on Ubuntu 12.04 with RVM, Nginx, Passenger and Oracle support

We have a new product ready and it is a Ruby on Rails webshop bundled with an ERP software written on Oracle Forms 6i. I will not go into the details of this work, maybe later i will make some posts of the process but as it is very linked to current software(only authentication is done with Devise, every other data and processing is done internally on Oracle database) there is no sense for me to explain it deeper. Off to the installation.

Server installation and configuration

First we need a clean install of Ubuntu server 12.04, x86 or x64 version will work all the same, but be careful later on when you download the Oracle instant client. On the installation, fill all the relevant data needed, and for installed services, choose only the ssh server, as you won’t be needing anything more. Another reminder: this will only be the webserver, assuming that you have the Oracle database installed somewhere in network reach.

After you login to your server for the first time, take your time to set up the ip address because it defaults to dhcp.
Edit the /etc/network/interfaces file and fill your address, gateway and dns servers(this is a new thing, i think starting in 12.04 /etc/resolv.conf gets updated whenever you restart networking, so everything you write there will get overwritten)

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static

After the config is saved, restart the networking and do a full update/upgrade of the server to get the latest packages installed:

sudo /etc/init.d/networking restart
sudo apt-get update
sudo apt-get -y dist-upgrade

After all is done, reboot your server.

Installing RVM and latest Ruby version

After your server is updated you can proceed with installing RVM and the latest stable Ruby(as i’m writing this, the latest version is 1.9.3p194 so i will be using this version)

First we install RVM prerequisites:

# rvm requires curl and git to install, and you will probably need them on your server so go ahead and install them
apt-get -y install git-core curl

# Installing RVM as sudo, to get RVM ruby system wide
curl -L | sudo bash -s stable

# sourcing rvm environment so you can use it untill you login again
source /etc/profile.d/

And that will install RVM and make it available for all users that belong to the rvm group(hint: edit /etc/groups and add rvm after the desired username). After installing RVM and adding our user to the  rvm group we are off to installing latest Ruby version

# install all requirements needed for YARV/MRI Ruby (you can easily get these by running 'rvm requirements' in the terminal)
sudo apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion

# install requirements needed for Oracle Instant client
sudo apt-get install libaio1

# install latest stable 1.9.3 and set it as default ruby version
rvmsudo rvm install 1.9.3 --default

# disable installation of RDoc and RI when installing gems
echo 'gem: --no-ri --no-rdoc'  >> ~/.gemrc

# install bundler gem, as you will later need for deployment
rvmsudo gem install bundler

 Installing Passenger and Nginx web server

After you have ruby and everything needed installer go and install passenger gem and nginx web server with it

# install  passenger gem
rvmsudo gem install passenger

# install passenger nginx module (and nginx if you haven't installed it yet), choose first option(Yes: download, compile and install Nginx for me) when it asks you what to do
# if there are more requirements the script will tell you and after you install them rerun the command
rvmsudo passenger-install-nginx-module

The installation will set up the nginx.conf file for you and show you how you can enable a rails site on your server. But i will include a sample config later on.
Just for convenience, symlink nginx conf folder that is in /opt/nginx/conf to /etc/nginx and download linode nginx startup/shutdown script

# symlink nginx conf folder to /etc/nginx
sudo ln -s /opt/nginx/conf /etc/nginx

# download linode nginx init script and create the service
wget -O
sudo mv /etc/init.d/nginx
sudo chmod +x /etc/init.d/nginx
sudo /usr/sbin/update-rc.d -f nginx defaults

Installing Oracle instant client

To connect your Rails application to Oracle database, you will have to install Oracle client, either full or instant one. As installing full client requires alien and converting .rpm packages to .deb it’s a bit of a hassle. Also, it will consume more space on your drive, and all that is unnecessary, we are trying to keep it small here.

First you should download zip files from Oracle site depending what architecture you are running:
Oracle Instant Client 11.2 for linux:  X86X64

Download only instantclient-basic, instantclient-sqlplus and instantclient-sdk zip archives and unzip them all into the same instantclient_11_2 folder. Now as sudo move that folder so the path is /opt/oracle/instantclient_11_2

After that you only have to add two environment variables to be able to install ruby-oci8 gem, which is prerequisite for running Ruby applications on Oracle database. Add the following lines to /etc/enviroment file


# as i am from Croatia, and we use our national date and money preferences, my NLS_LANG is this one, yours will maybe be different

After you reboot you have to symlink the oracle library so it will function properly(i don’t know why they don’t do this themselves).

ln -s /opt/oracle/instantclient_11_2/ /opt/oracle/instantclient_11_2/

After that try and install ruby-oci8 gem.

rvmsudo gem install ruby-oci8

If there are no errors, and there should not be if you followed the guide, you are set to deploy your application on the server you just installed. In the next post, i plan to write something about tips, tricks and caveats of developing Rails applications on Oracle database.

Useful links to get and learn about all the stuff i have mentioned in the post:

Ruby Version Manager(RVM):
Oracle Instant Client 11.2 for linux:  X86, X64
Passenger server:

Rails 3.1 beta on Ubuntu

As i have written before, i use Ubuntu for my rails development, and have been using it as my main OS last 10 months. I have been trying all the rails 3.1 beta hype and encountered a problem running 3.1 apps on my machine.

The main problem is with CoffeScript and its compiling into “real” JavaScript. So here is an easy way to enable your machine for rails 3.1. You have to install Node.js on your machine( i have tried all other Javascript runtimes with no luck). All the instructions for other platforms are listed on the project’s GitHub page, i will include only the ubuntu procedure here.

sudo apt-get install python-software-properties

sudo add-apt-repository ppa:jerome-etienne/neoip

sudo apt-get update

sudo apt-get install nodejs

And that is all, hope i have made your life easier at least a bit.