Beberapa minggu lalu saya diminta untuk membuat simulasi sederhana dari dispatching system untuk taksi menggunakan Ruby on Rails. Saya sempat membahas sekilas mengenai framework ini pada post saya sebelumnya. Salah satu fitur yang diminta dari dispatching system tersebut adalah fitur untuk mencari taksi terdekat dari lokasi calon penumpang taksi. Saya menggunakan Geokit plugin untuk Rails yang sangat mempermudah proses pencarian.
Berikut adalah langkah-langkahnya:
- Edit Gemfile pada Rails project, tambahkan baris berikut:
gem 'geokit-rails'
- Buka Terminal pada direktori Rails project, kemudian jalankan perintah ini untuk menginstalasi geokit-rails plugin.
$ bundle install
- Persiapkan database server yang compatible, saya menggunakan MySQL pada post ini. Berikut adalah snippet config/database.yml yang digunakan.
default: &default adapter: mysql2 encoding: utf8 pool: 25 timeout: 5000 username: root password: socket: /tmp/mysql.sock development: <<: *default database: booking_dev # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default database: booking_test production: <<: *default database: booking
- Buat model Driver sebagai representasi sopir taksi. Sopir taksi ini juga memiliki 2 atribut lokasi yaitu longitude dan latitude.
$ rails generate scaffold Driver name:string phone:string latitude:decimal{10.6} longitude:decimal{10.6}
- Jalankan script migration untuk membuat tabel drivers.
$ bin/rake db:migrate RAILS_ENV=development
- Persiapkan seed data menggunakan rake task. Buat file db/seeds.rb untuk mengisi tabel drivers. Misalnya seperti ini:
Driver.delete_all Driver.create!(name: 'Adam Ashton', phone: '+62811234567', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6)) Driver.create!(name: 'Brian Borrowick', phone: '+62812234644', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6)) Driver.create!(name: 'Charlie Chuckles', phone: '+62813234698', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6)) Driver.create!(name: 'Damian Delaware', phone: '+62814234526', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6)) Driver.create!(name: 'Edward Ernst', phone: '+62815349347', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6)) Driver.create!(name: 'Finn Flannigan', phone: '+62816287667', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6)) Driver.create!(name: 'Gregory Georgetown', phone: '+62817255667', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6)) Driver.create!(name: 'Hendrick Henderson', phone: '+62818200967', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6)) Driver.create!(name: 'Ian Impala', phone: '+62819235467', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6)) Driver.create!(name: 'Jeremy Jefferson', phone: '+62810234887', latitude: (rand -90.000000..90.000000).round(6), longitude: (rand -180.000000..180.000000).round(6))
- Jalankan rake task untuk menghasilkan seed data pada poin sebelumnya.
$ bin/rake db:seed
- Validasi di MySQL client bahwa perintah rake sebelumnya berjalan dan data berhasil di-generate.
Tabel drivers via Sequel Pro app - Aktifkan plugin geokit-rails pada model Driver dengan cara menambahkan fungsi acts_as_mappable pada file app/models/driver.rb seperti berikut:
class Driver < ActiveRecord::Base acts_as_mappable default_units: :kms, default_formula: :sphere, distance_field_name: :distance, lat_column_name: :latitude, lng_column_name: :longitude end
- Uji coba dengan menjalankan perintah berikut pada rails console.
$ rails console irb(main):001:0> jeremy = Driver.find(10) irb(main):002:0> distance = 10000 irb(main):003:0> Driver.within(distance, :origin => jeremy).first
- Perintah tersebut seharusnya akan mengembalikan sopir terdekat dari Jeremy Jefferson dalam radius 10.000 km :) Jika perintah tersebut tidak mengembalikan apa-apa tapi tidak error, berarti seed datanya harus kita persempit lagi lokasinya, hehe
No comments:
Post a Comment