Jumat, 11 September 2015

Active Job di Ruby on Rails

Kali ini kita akan bersama-sama belajar mengenal Active Job di Ruby on Rails. Kita akan mempelajari pengertiannya, manfaatnya dan contoh penggunaannya.

Active Job adalah sebuah framework, digunakan untuk mendlekarasikan sebuah pekerjaan yang nantinya akan dijalankan dala sebuah urutan di backend. Pekerjaan yang dimaksud disini bisa pekerjaan apa saja, mulai dari pembersihan data, pengurutan data, mailing dan pekerjaan lainnya yang bisa dikerjakan secara pararel.

Secara umum manfaat penggunaan Active Job adalah sebagai wrapper background job processing sehingga memudahkan developer untuk menuliskan code secara general. Active job menerjemahkan syntax yang ditulis developer agar bisa dibaca background engine yang digunakan. Terdapat tiga kondisi yang biasanya dibutuhkan sebuah active job:
  1. Sebuah proses yang membutuhkan External API untuk melakukan proses.
  2. Sebuah proses yang memerlukan banyak perhitungan atau proses (contohnya memproses sebuah gambar).
  3. Mengirimkaan email atau posting ke media lain (social media, blog dll).
Namun dalam prakteknya active job belum bisa berjalan sendiri, diperlukan library backend agar bisa menjalankannya. Rails 4 sudah menyediakan beberapa adapter untuk backend tersebut, namun kita masih harus menginstal gem dari backend yang akan kita pakai. List adapter yang bisa kita gunakan di rails bisa klik link ini.

Agar semakin paham, kita akan langsung mencoba menerapkannya dalam sebuah aplikasi sederhana. Kita akan mencoba menghapus beberapa data sekaligus melalui active job dengan adapter Sidekiq.

Buat aplikasi sederhana
Pertama siapkan sebuah aplikasi sederhana dengan dua model yaitu model User dan model Article dimana user has many articles. Kemudian isikan beberapa data di dalamnya. Anda bisa memanfaatkan aplikasi yang sudah pernah kita buat di belajar bareng kita sebelumnya (kalau ketinggalan bisa klik di sini)

Install sidekiq
Setelah aplikasi sederhana sudah berjalan selanjutnya kita install dulu sidekiq di aplikasi kita, caranya dengan memasukan gem sidekiq ke dalam gemlist.

gem 'sidekiq', '3.2.5'

Lalu lakukan bundle install.
Setelah itu kita akan membuat config file untuk sidekiq. Buat sebuah file di path config dengan nama sidekiq.yml

config/sidekiq.yml

:concurrency: 25
:pidfile: ./tmp/pids/sidekiq.pid
:logfile: ./log/sidekiq.log
:queues:
  - default

Untuk mengecek apakah sidekiq sudah terinstall dengan benar, jalankan server ( $ rails s) kemudian buka tab baru dari path tersebut. 
jalankan perintah:

sidekiq -C config/sidekiq.yml

Kalo tidak ada masalah seharusnya kurang lebih tampilannya akan seperti ini:

Jadi sekarang kita seolah-olah menjalankan dua server, satu untuk server rails dan yang satu untuk sidekiq. Biarkan keduanya berjalan namun bila ingin menghentikannya tinggal menekan kombinasi tombol Ctrl + C

Membuat active job
Sekarang kita akan memulai untuk membuat file active job dan melakukan beberapa penyesuaian agar bisa menjalankan active job dengan adapter sidekiq.
Pertama kita buat dulu file active job, caranya dengan mengetikan perintah ini di terminal:
rails generate job articles_cleanup

Secara otomatis akan terbentuk sebuah path baru di dalam app yaitu path jobs dan sudah ada satu file didalamnya dengan nama articles_cleanup_job.rb, kemudian kita isi file tersebut dengan code yang kurang lebih seperti ini:

app/jobs/articles_cleanup_job.rb
class ArticlesCleanupJob < ActiveJob::Base
  queue_as :default

  def perform(user_id)
    user = User.find(user_id)
    count = 0
    if user
      puts "Prepare to Delete article form user #{user.name}"
      articles = user.articles
      if articles
        articles.each do |article|
         
count += 1 if article.destroy
        end   
      end
    puts "Delete article finished, deleted articles = #{count}"
      end   
  end
end

Keterangan:
Agar nanti kita bisa tahu sidekiq kita telah benar-benar mengeksekusi proses delete article, kita tambahkan puts "Prepare to Delete article form user #{user.name}"  di awal proses dan puts "Delete article finished, deleted articles = #{count}" setelah proses selesai

Kemudian kita buat juga sebuah file di path config/initializers dengan nama active_job.rb lalu kita isi dengan code:

config/initiaizers/active_job.rb
ActiveJob::Base.queue_adapter = :sidekiq

Memanfaatkan active job di aplikasi
Pembuatan file active_job dan setup sidekiq sudah selesai, sekarang saatnya mencobanya pada aplikasi.
Saya akan memanfaatkan aplikasi yang sebelumnya dibuat pada sesi sebelumnya (klik di sini bila ingin membaca sesi sebelumnya), tinggal tambahkan sebuah model Article (isinya bebas) yang ber-relasi dengan model User, dimana user has_many articles.

Buat juga sebuah articles_controller dan sebuah method di controller tadi yang nanti berfungsi untuk memanggil active job tadi.


articles_controller.rb
class ArticlesController < ApplicationController
  def delete_articles
      ArticlesCleanupJob.perform_later(params[:id])
      redirect_to root_url
  end
end
 
Jangan lupa untuk mendaftarkan path-nya di routes.rb

routes.rb

resources :articles do
  member do
    get 'delete_articles'
  end

end

Pada view/home/index.html.erb juga kita ubah sedikit untuk memanggil method delete_articles tadi

view/home/index.html.erb
<%if current_user %>
  Conglartulation, you login with facebook
  </br>
  <%= link_to "Delete All articles this user"

      , delete_articles_article_path(current_user.id)%>
<%else%>
  <%= link_to "Login with facebook", "auth/facebook"%>

<%end%>

Sekarang kita akan mencobanya, tapi sebelumnya kita isi dulu tabel article dengan beberapa dummy data, bisa diisi secara random namun yang perlu diingat user_id harus terisi dengan id user yang sudah ada.

Berikut tampilan sesudah login




 Kemudian kita klik "Delete All articles this user". lalu cek di server aplikasi kita

Dari situ akan terlihat sebuah baris log:
[ActiveJob] Enqueued ArticlesCleanupJob (Job ID: 3f3571e7-81d7-48b6-a4a3-55ca7bc6dfaf) to Sidekiq(default) with arguments: "2"


Yang berarti active job kita sudah dijalankan dengan memanfaatkan sidekiq. Bisa kita buktikan dengan melihat server sidekiq

 Yup, penanda awal proses dan setelah proses sudah tertulis, berarti sidekiq telah menjalankan proses penghapusan Articles untuk user tersebut.

Demikianlah pengenalan active_job pada rails 4 secara sederhana ini. Sebenarnya pembelajaran mengenai active joba baik teknik, maupun pemanfaatannya masih sangat luas sekali, dan mungkin akan kita pelajari bersama lain waktu.
Semoga belajar bareng kali ini bermanfaat dan Happy Coding (^.^)


Sumber:
- Active Job Basics 
- How to Integrate Sidekiq With ActiveJob
- Gem Sidekiq

Rabu, 02 September 2015

Login dengan Omniauth pada Rails Part 1 (Facebook)

Sebelumnya kita pernah membahas apa itu User Authentication, bila Anda ketinggalan artikelnya, bisa klik link ini http://www.belajarrubyonrails.com/2015/06/apa-itu-user-authentication.html untuk mendapat pengertian dan penjelasannya. Kali ini kita akan mencoba menerapkannya di dalam sebuah aplikasi Ruby on Rails.

Kita akan mencoba memanfaatkan gem Omniauth dan account facebook. Secara singkat langkah-langkah yang harus kita lakukan adalah:
  1. Buat sebuah aplikasi di facebook developer  dan buat sebuah aplikasi baru Ruby on Rails
  2. Masukan Gem Omniauth dan Gem Omniauth-Facebook
  3. Buat sebuah model User
  4. Buat Sessions Controller
  5. Membuat Omniauth initializer
  6. Menghubungkan login user dengan facebook.
  
Oke, pertama kita harus membuat dahulu sebuah aplikasi di facebook developer. Lalu bila sudah, kita catat dulu app_id dan app_secret-nya. Kemudian kita lanjutkan dengan membuat sebuah aplikasi sederhana Ruby on Rails. Jangan lupa untuk memasukan gem omniauth di dalam Gemfile:

gem 'omniauth'
gem 'omniauth-facebook', '1.4.0'

Jalankan bundle install.

Selanjutnya kita buat dulu halaman root untuk aplikasi baru kita. Seperti biasa kita akan menggunakan controller home dan action index sebagai root aplikasi. Kita buat secara sederhana saja.

home_controller.rb :
class HomeController < ApplicationController
  def index    
  end
end

app/views/home/index.html.erb:
<%if current_user %>
  Congratulation, you login with facebook
<%else%>
  <%= link_to "Login with facebook", "auth/facebook"%>
<%end%>  

Membuat Model User

Sekarang kita akan membuat model User

rails g model User provider uid name oauth_token
oauth_expires_at:datetime
keterangannya adalah:
  • uid : untuk menyimpan id dari facebook
  • name: menyimpan nama user yang diambil dari facebook
  • oauth_token: token yang diberikan facebook
  • oauth_expires_at: untuk mengetahui masa berlaku token.

Jalankan rake db:migrate untuk membuat tabel users di database. Kemudian kita isi model User tadi dengan beberapa logic code agar bisa menampung data dari facebook dan diisikan ke dalam database kita.
model user.rb
class User < ActiveRecord::Base
  def self.from_omniauth(auth)

    where(provider: auth.provider
      , uid: auth.uid).first_or_initialize.tap do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.name = auth.info.name
      user.oauth_token = auth.credentials.token
   user.oauth_expires_at = Time.at(auth.credentials.expires_at)
      user.save!
    end
  end
end

Lalu sekarang kita akan mengisi application_controller.rb dengan logic code, agar bisa menyimpan session current_user.

application_controller.rb :
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  private
  def current_user   

    if session[:user_id]
      @current_user ||= User.find(session[:user_id])
    end

  end
  helper_method :current_user
end

Membuat Session Controller

Session controller dibuat agar nantinya aplikasi kita bisa menerima callback dari auth facebook, yang kemudian memprosesnya agar bisa menjadi login user di aplikasi  kita.

sessions_controller.rb :
class SessionsController < ApplicationController
  def create
    user = User.from_omniauth(env["omniauth.auth"])
    session[:user_id] = user.id
    redirect_to root_url
  end

  def destroy
    session[:user_id] = nil
    redirect_to root_url
  end
end

Owh iya, tadi untuk halaman home, kita belum mendaftarkannya di routes.rb, oleh karena itu kita daftarkan dulu sekaligus kita daftarkan path-path yang dibutuhkan agar aplikasi kita bisa berjalan.

yang perlu kita daftarkan di config/routes.rb :
root 'home#index'
match 'auth/:provider/callback', to: 'sessions#create', via: [:get, :post]
match 'auth/failure', to: redirect('/'), via: [:get, :post]
match 'signout', to: 'sessions#destroy', as: 'signout', via: [:get, :post] 

Membuat Omniauth initializer
Kali ini kita akan memanfaatkan gem yang sudah kita instal tadi dengan membuat initializer-nya.
Buat sebuah file omniauth.rb di dalam path config/initializers

isi dari config/initializers/omniauth.rb adalah:

OmniAuth.config.logger = Rails.logger

Rails.application.config.middleware.use OmniAuth::Builder do

  provider :facebook, 
  'YOUR APP_ID', 
  'YOUR APP_SECRET'
end
 keterangan: 
'YOUR APP_ID'   => Di isi dengan app_id yang kita dapat dari aplikasi facebook tadi.
'YOUR APP_SECRET' => Di isi dengan app_secret_code.
bila masih bingung letaknya, ada di halaman apps, lalu pilih setting :



Kemudian kita akan membuat sebuah file coffescript yang bernama facebook.js.coffescript yang akan membantu kita dalam memunculkan authentikasi pada account facebook. Letakan file facebook.js.coffescript di dalam path app/assets/javascripts .
Isi dari  app/assets/javascripts/facebook.js.coffescript:
jQuery ->
  $('body').prepend('<div id="fb-root"></div>')

  $.ajax
    url: "#{window.location.protocol}//connect.facebook.net/en_US/all.js"
    dataType: 'script'
    cache: true


window.fbAsyncInit = ->
  FB.init(appId: 'YOUR APP_ID', cookie: true)

  $('#sign_in').click (e) ->
    e.preventDefault()
    FB.login (response) ->
      window.location = '/auth/facebook/callback' if response.authResponse

  $('#sign_out').click (e) ->
    FB.getLoginStatus (response) ->
      FB.logout() if response.authResponse
    true

Nah kita kembali harus memasukan app_id dari aplikasi facebook kita tadi ke dalam code coffescript.

Menghubungkan User dengan Login Facebook

Untuk langkah terakhirnya, kita cukup menampilkan Nama user yang login dari facebook di halaman index atau di layout. Kali ini saya akan mencotohkan bila ditulis di dalam layout.

Di file app/views/layouts.application.html.erb tambahka kode:


<% if current_user %>
   Welcome <strong><%= current_user.name %></strong>!
   <%= link_to "Sign out", signout_path, id: "sign_out" %>

<% end %>
sebelum <%= yield %>

Dan selesailah percobaan kita. Bila tidak ada kesalahan seharusnya hasilnya kurang lebih seperti ini:
1. Saat pertama masuk ke halaman home

2. Saat mekalukan authentikasi facebook

3. Selesai, selamat Anda telah sukses login dengan facebook, EUREKAAAA !!!




Yup, dari tutorial sederhana ini kita bisa mengembangkannya menjadi lebih bermacam-macam sesuai kebutuhan.
Demikian belajar bareng kali ini, semoga bisa bermanfaat buat kita semua, Happy Coding (^.^)

Sumber:
- Authentication with Facebook and OmniAuth.

- Rails and OmniAuth
- Rails 4.1.5 omniauth strong parameters

Selasa, 01 September 2015

Concerns di Rails4

Anda mungkin memperhatikan bahwa di dalam Rails 4 terdapat 1 buah path yang ada secara default di dalam path model dan path controller. Path tersebut adalah "Concerns"
Lalu sebenarnya makanan jenis apa sih concerns ini? Dalam artikel ini kita akan mencoba untuk membahasnya.
Fungsi dari concerns secara umum adalah untuk membantu kita agar code yang kita tulis bisa lebih DRY(Don't Repeat Yourself) dan lebih "menguruskan" code di dalam sebuah blok model.

1. Untuk membuat code kita lebih DRY
Kita contohkan kita memiliki 3 model yang saling berhubungan

model Article
class Article < ActiveRecord::Base
  has_many :comments, as: :commentable
  def find_first_comment
    comments.first(created_at DESC
  end
  
  def self.least_commented
    # mengembalikan article yang paling sedikit commentnya
  end
end

model Question
class Question < ActiveRecord::Base
  has_many :comments, as: :commentable
  
  def find_first_comment
    comments.first(created_at DESC)
  end
  
  def self.least_commented
    # mengembalikan article yang paling sedikit commentnya
  end   
end

model Comment
class Comment < ActiveRecord::Base
  belongs_to :commentable, polymorphic: true
end

Dapat dilihat ketiga model tersebut saling berhubungan dengan comment sebagai polymorphicnya.
Terjadi pengulangan code pada model Articel dan Question, padahal proses dan hasil yang diinginkan adalah sama. Nah, dengan menggunakan concerns kita bisa merubahnya menjadi lebih DRY. Untuk melakukannya kita cukup membuat sebuah file rb di dalam path app/models/concerns:

Module Commentable
module Commentable
  extend ActiveSupport::Concern

  included do
    has_many :comments, as: :commentable
  end
  
  # mencari komentar pertama
  def find_first_comment
    comments.first(created_at DESC)
  end
  
  module ClassMethods 
    def least_commented
      # mengembalikan article yang paling sedikit commentnya
    end
  end
end

Setelah module tersebut dibuat kita bisa memanggilnya ke dalam model Article dan Question, kurang lebih menjadi seperti ini:

class Article < ActiveRecord::Base
  include Commentable  
end

class Question < ActiveRecord::Base
  include Commentable   
end

Sedangkan untuk model Comment tetap biarkan seperti semula.

Inti penggunaan ini adalah, menggantikan semua code yang ada sebelumnya di model Article dan Question dengan module Commentable, dan module ini bisa diimpelmentasikan ke semua model yang membutuhkan dengan catatan bahwa fungsi dan prosesnya bisa dipakai untuk ke dua model tersebut.

Kalau kita perhatikan terdapat dua cara penulisan method di Commentable.
Pertama:
def <method_name> 
end

Kedua:
module ClassMethods    
  def <method_name>
  end   
end

Untuk code yang pertama digunakan apabila method merupakan instance method di dalam model ( def <methode_name> end). Sedangkan yang kedua dipakai apabila method merupakan class method yang ada di dalam model  ( def self.<methode_name> end).

 2. Lebih "menguruskan" code di dalam sebuah blok model
Terkadang kita akan menjumpai sebuah model dengan banyak sekali method di dalamnya. Bahkan bisa sampai ribuan atau bahkan puluhan ribu baris. Tentu saja hal ini akan sangat menyulitkan bila kita menemukan bug dan harus memeriksa depedency bug tersebut.
Kita harus mensederhanakannya agar lebih enak dipandang dan memudahkan kita nantinya.
Dengan concern kita bisa melakukannya.
Masih menggunakan contoh 3 model tadi:
class Article < ActiveRecord::Base
  has_many :comments
  has_many :questions

  def find_first_comment
    # mencari comment pertama dalam sebuah artikel
  end

  def self.least_commented
    # mencari article dengan comment paling sedikit
  end

  def self.most_questionable
    # returns articel yang paling banyak memiliki question
  end

  def has_question(question_id)
    # returns true jika terdapat question yang diinginkan
  end
end

Kita bisa membuat code di dalam model Article menjadi lebih pendek lagi dengan memanfaatkan concerns. Di dalam path app/models/concerns kita menambahkan dua module:
module quetionable
module Quetionable
  extend ActiveSupport::Concern
  
  included do
    has_many :quetions
  end
  
  def has_quetion(attender_id)
    # returns true jika terdapat question yang diinginkan
  end
  
  module ClassMethods
    def most_quetionable
      # returns articel yang paling banyak memiliki question
    end
  end
end

module commentable
module Commentable
  extend ActiveSupport::Concern
  
  included do
    has_many :comments
  end
  
  def find_first_comment
    # mencari comment pertama dalam sebuah artikel
  end
  
  module ClassMethods
    def least_commented
      # mencari article dengan comment paling sedikit
    end
  end
end

Dengan menggunakan concern diatas kita bisa merubah code di model Article menjadi:
class Article < ActiveRecord::Base
  include Commentable
  include Quetionable
end

Terlihat menjadi sangat pendek bukan?
Penggunannya bisa kita sesuaikan dengan kondisi code kita masing - masing.
Untuk controller penggunannya juga kurang lebih sama dengan model hanya pathnya saja berbeda.

Semoga artikel ini bisa membantu untuk lebih memahami mengenai "concerns" di rails 4. Happy coding(^.^)

Sumber:
Api ruby on rails
How to use concerns in Rails 4 
- Code Concerns in Rails 4 Models
- Controller Concerns in Rails 4 

Kamis, 25 Juni 2015

Apa Itu User Authentication ?

Definisi User Authentication

Authentication adalah tindakan mengkonfirmasi kebenaran suatu bagian dari data (datum) atau suatu entity.

User Authentication sendiri berarti melakukan konfirmasi data user yang sebelumnya sudah tersimpan.

Contoh kasus User Authentication

Kemudian muncul pertanyaan bagaimana cara sistem melakukan konfirmasi data (dalam konteks ini data user) ? hal tersebut dapat kita cari pada attribut-attribut pembangun data user sendiri. Berikut gambaran sederhana dari tabel user yang sering digunakan pada suatu sistem

Dari attribut diatas pembaca pasti sudah kenal dengan suatu proses dalam sistem yang berhubungan dengan user authentication ini... yup betul sekali, Form Login merupakan bentuk dari suatu proses user authentication

Berikut penjelasan proses login secara detail:

  • Pengguna memasukan data username dan password.
  • Data dari form ditermia oleh sistem, sistem yang baik melakukan enkripsi data terhadap password yang dimasukan oleh pengguna.
  • Data username dan password(yang sudah ter enkripsi) kemudian dicocokan dengan data yang ada di database.
  • Bila cocok proses authentication sudah ok !
  • Bila tidak cocok dengan data yang terdapat di database, maka sistem akan menolak.

Perkembangan User Authentication

Seiring banyaknya sistem yang berkembang saat ini, dan merujuk dari kesamaan tiap sistem yang mengharuskan penggunanya untuk melakukan authentication disetiap pengaksesannya maka dirancanglah Single Sign On (SSO)

Single Sign On (SSO) merupakan cara pengambilan properti data dari sistem yang lain, dengan menggunakan data tersebut pengguna tidak memerlukan login kembali untuk melakukan aktifitas di sistem yang berbeda, berikut contoh penerapan sistem Single Sign On

Dengan diterapkannya single sign on terdapat beberapa keuntungan
Dari segi pengguna:

  1. Pengguna tidak lagi melakukan registrasi data ditiap sistem yang akan digunakannya.
  2. Pengguna tidak perlu mengingat banyak mengenai username dan passowrd yang ia gunakan pada setiap sistem.
Dari penyedia sistem:
  1. Jika dilihat dari segi data yang didapat dari sistem single sign on, ternyata lebih lengkap dari sistem registrasi yang lazim dibuat, data-data seperti hari kelahiran, gender, nama lengkap, lokasi, hobby, ketertarikan, photo pengguna (avatar), dan lain sebagainya yang disediakan oleh beberapa sosial media yang mendukung single sign on ini
  2. Dari keuntungan nomor 1 tentunya sebagai pihak penyedia sistem dapat melakukan banyak aksi yang berhubungan dengan menjaga loyalitas para penggunanya.
  3. Keuntungan lain yaitu penyedia sistem dapat mengetahui bahwa pengguna sudah ter-verifikasi pada sistem lain, karena sering kali pengguna login/registrasi menggunakan email atau identitas palsu

Penerapan User Authentication pada suatu sistem dengan bahasa pemrograman ruby on rails memiliki banyak cara. Pada posting selanjutnya kita akan membahas bagaimana cara menerapkan User Authentication dengan menggunakan gems devise ruby on rails

Rabu, 24 Juni 2015

Instalasi beberapa versi Ruby dengan RVM atau RBENV


Persamaan dan Perbedaan RVM dan RBENV

Kesamaan :
  • Dapat membantu untuk melakukan instalasi ruby dengan versi yang berbeda-beda.
  • Instalisasi lebih mudah dibandingkan dengan cara yang lain (compile source code).
Perbedaan :
  • Pada penggunaan RVM ruby gems terkadang terinstall dua kali atau lebih.
  • Penggunaan bash sebelum menjalankan RVM
  • RVM handal di fitur-fiturnya
  • RBENV lebih ringan
Perhatian :
RVM dan RBENV tidak kompetibel satu sama lain, jadi harus memilih ingin menggunakan RVM atau RBENV.

Menggunakan RVM (Ruby Version Manager)

Persiapan
Pertama-tama pastikan sistem linux anda memiliki paket aplikasi berikut :
  • bash versi 4.1 atau lebih baru
  • Curl
  • Git Versi 1.7 atau lebih baru
  • Patch
Untuk mengetahui sudah tersedia atau belum ikuti langkah berikut ini :
  • Bash
  • $ bash --version
  • Curl
  • $ curl --version
  • Git
  • $ git --version
  • Patch
  • $ patch --version
jika ada paket aplikasi yang belum terinstall atau tidak memenuhi syarat versi minimal maka perlu di-update atau install versi yang lebih baru dengan cara update repository paket aplikasi dan dilanjutkan dengan menginstall paket aplikasi yang diperlukan
CentOS/RH/Fedora/AMI
  $ sudo yum update
  $ sudo yum install -y bash curl git patch
Ubuntu/Debian
  $ sudo apt-get update
  $ sudo apt-get install bash curl git-core patch
Gentoo
  $ sudo emerge --sync
  $ sudo emerge bash curl git patch

Install RVM

Berikut merupakan tahapan dari instalasi RVM, silakan buka terminal anda dan ikuti langkah-lankah berikut :
  • Install paket-paket yang berhubungan dengan RVM
  • $ sudo apt-get install libgdbm-dev libncurses5-dev automake libtool bison libffi-dev
  • Setup git agar dapat melakukan download dan install RVM
  • $ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
  • Download RVM melalui curl command:
  • $ curl -sSL https://rvm.io/mpapis.asc | gpg --import -
    $ curl -L https://get.rvm.io | bash -s stable
  • Kemudian Load RVM ke shell
  • $ source ~/.rvm/scripts/rvm
  • Agar RVM dapat berjalan dengan baik diperlukan beberapa dependency paket. Untuk mengetahui paket apa saja yang diperlukan maka dapat dilihat dengan mengetikan command line berikut pada terminal anda :
  • $ rvm requirements
    Berikut merupakan hasil dari perintah diatas (Contoh diambil dari sistem berbasis Gentoo linux)

    Lihat pada bagian
    Additional Dependencies:
    # For Ruby / Ruby HEAD (MRI, Rubinius,& REE), install the following: 
    ruby|ruby-head: emerge libiconv
    readline zlib openssl curl git libyaml sqlite libxslt libtool gcc
    autoconf automake bison m4
  • Gunakan rvmsudo untuk melakukan install paket depedency yang dibutuhkan oleh RVM untuk contoh diatas dapat melakukan command sebagai berikut
  • $ rvmsudo emerge libiconv readline zlib
    openssl curl git libyaml sqlite libxslt libtool gcc autoconf automake bison m4

Install Ruby - RVM

  • Untuk mengetahui versi ruby yang dapat kita install dapat menggunakan perintah berikut
  • $ rvm list known
  • Menginstall versi ruby tertentu (pada contoh ini kami menggunakan versi 2.2.2)
  • $ rvm install 2.2.2
  • Menentukan default ruby yang akan diguanak
  • $ rvm use 2.2.2 --default
  • Untuk melihat versi ruby yang sudah terinstall
  • rvm list

Upgrade/update RVM

$ rvm update

Saran pada penggunaan RVM

RVM dapat digunakan setelah mengeksekusi bash seperti berikut
$ /bin/bash --login
Namun beberapa variant linux sudah membuat bash command default ketika system berjalan, untuk yang masih memerlukan eksekusi command diatas berikut saran dari kami
  • Install gnome terminal
  • Untuk melakukan setup terminal klik Edit > Profile Preferences > masuk ke tab Title and Command
  • Centang pada pilihan Run command as login shell, seperti gambar berikut

Menggunakan RBENV

Persiapan

Install paket yang dibutuhkan untuk compile ruby
CentOS/Fedora/RH/AMI
$ sudo yum update
$ sudo yum install -y gcc-c++ patch readline readline-devel curl git zlib zlib-devel libyaml-devel 
libffi-devel openssl-devel make bzip2 autoconf automake libtool bison iconv-devel
Ubuntu/Debian
$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
Gentoo
sudo emerge libiconv readline zlib
openssl curl git libyaml sqlite libxslt libtool gcc autoconf automake
bison m4

Install RBENV

Ikuti command dibawah ini untuk install RBENV pada linux anda :
cd
git clone git://github.com/sstephenson/rbenv.git .rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL

git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL

git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash

Install Ruby menggunakan ruby-build

Install ruby-build
rbenv install 2.2.2
rbenv global 2.2.2
ruby -v

Refresh/rehash instalasi ruby atau gem

Lakukan rbenv rehash setelah install versi ruby baru atau setelah install gem baru dengan menjalankan perintah
rbenv rehash
update rubygems
Melihat versi ruby yang sudah terinstall
rbenv versions
Menjadikan ruby default
rbenv global 2.2.2
Sumber:

Rabu, 18 Maret 2015

Cara penggunaan reCAPTCHA di Rails application

Untuk pengimplementasian reCaptcha di Rails application kita bisa menggunakan gem recaptcha.

Langkah pertama kita tambahkan gem recaptcha ke Gemfile

gem 'recaptcha'

Selanjutnya di terminal kita menjalankan perintah :

$ bundle install

Sekarang kita tinggal mengkonfigurasinya dibagian config/initializers/recaptcha.rb untuk penggunaan di aplikasi Rails. Tapi sebelumnya pastikan bahwa anda mempunyai public_key dan private_key untuk aplikasi anda, jika belum anda dapat membuatnya disini.

Recaptcha.configure do |config|
  config.public_key  = '<public_key anda>'
  config.private_key = '<private_key anda>'
end

Langkah selanjutnya adalah kita tinggal menggunakan recaptcha_tags disetiap form yang kita inginkan.

Contoh :

<%= form_for @foo do |f| %>
  '#...#'
  <%= recaptcha_tags %>
<% end %>

Lalu gunakan function verify_recaptcha untuk verify captcha di controller, contoh:

respond_to do |format|
  if verify_recaptcha(:model => @foo, :message => "Oh! It's error with reCAPTCHA!") && @foo.save
    # ...
  else
    # ...
  end
end

Demikian cara penggunaan reCaptcha dalam Rails application.

Keep Learning and Happy Coding :)

Senin, 16 Maret 2015

Penggunaan gem permanent_record dan nested_form dalam satu rails aplikasi

Dalam artikel ini kita akan membahas tentang permasalahan yang timbul ketika kita mempunyai gem 'permanent_records' dan gem 'nested_form' di aplikasi Rails kita.  

STUDI KASUS

Misal dalam aplikasi yang kita buat terdapat model Order dan  LineItem.


order.rb

class Order < ActiveRecord::Base
  has_many :line_items, :dependent => :destroy
  accepts_nested_attributes_for :line_items, allow_destroy: true
end

line_item.rb

class LineItem < ActiveRecord::Base
  belongs_to :order
end


Di orders_controller.rb untuk Rails 4 jangan lupa dibagian strong_params untuk menyertakan attributes dari line_items

orders_controller.rb

def order_params
  params.require(:order).permit(:order_number, :order_date,         :line_items_attributes => [:id, :item_name, :price, :_destroy])
end

Yang harus diingat untuk nested_form di rails 4 adalah memasukan attributes "_destroy" di attributes child, jika attibutes ini tidak dimasukan maka ketika kita menghapus nested maka record tersebut akan tetap ada di database.

RECORD TETAP ADA?

Inilah yang penulis baru-baru ini alami, meskipun semua attributes dari line_items model sudah dimasukan di strong params tentu saja dengan penambahan "_destroy" ternyata record yang dihapus dinested masih tetap tampil ketika melakukan edit untuk order.

SOLUSI

Yang dilakukan pertama kali adalah mengecek schema.rb dari table line_item apakah memiliki column deleted_at atau tidak. Jika ternyata ada, maka dua cara yang pernah penulis lakukan untuk mengatasi permasalahan diatas, yaitu :

1 . Membuat migrasi baru untuk meremove column deleted_at
 
$ rails g migration remove_deleted_at_in_line_items 
$ rake db:migrate

2. Edit orders_controller.rb

def update
  @order.line_items.where('deleted_at IS NOT NULL').delete_all
  ...
end

Setelah itu lakukan pengetesan untuk menghapus nested record, dan boom record yang semula tidak bisa dihapus akan hilang.

Demikian yang bisa disampaikan untuk pembahasan ini,

Selamat mencoba dan Happy Coding.

Cara Implementasi Soft Delete dengan gem 'permanent_records'

Soft delete adalah sebuah solusi ketika kita membutuhkan suatu data / record tidak muncul di view tapi masih tersimpan di database sebagai "archive". Jadi, ketika ada keperluan untuk mencari / mengembalikan ( restore ) data yang sudah dihapus user, kita masih bisa melakukan query untuk mencari dan menampilkan data tersebut.

Contoh: user menghapus data penjualan hari ini dengan tidak sengaja. Karena implementasi soft delete, system admin akan mampu melakukan restore data tersebut dengan relatif mudah.

Untuk implementasi soft delete, kita bisa menggunakan gem 'permanent_records'. Berikut ini cara integrasinya:

INSTALASI

Masukan gem 'permanet_records' di gemfile:

gem 'permanent_records', github: 'JackDanger/permanent_records'

selanjutnya jalankan di terminal:

$ bundle install

KEGUNAAN

Setelah penginstalan selesai dilakukan kita dapat menjalankan beberapa method untuk melakukan pengetesan.

User.find(3).destroy # akan menjalankan action soft_delete untuk user yang bersangkutan
User.find(3).destroy(:force) # akan menjalankan action delete dan record akan dihapus dari database
User.destroy_all # Soft-delete semua user
User.delete_all # Permanent delete semua user

Bagaimana menampilkan record?

User.deleted.find(...) # akan menampilkan user yang sudah tersoft_delete
User.not_deleted.find(...) # hanya akan menampilkan record yang belum disoft_delete

Dapatkah kita mengembalikan record yang sudah di soft_delete?

User.find(3).destroy
User.find(3).revive #restore use yang sudah di soft-delete

Demikian sedikit pembahasan untuk gem 'permanent_records' yang dapat kami berikan, semoga bermanfaat. Untuk lebih detail tentang gem ini, silahkan kunjungi laman berikut.

Happy Coding :)

Implementasi gem 'nested_form' di Rails 4

Dalam tutorial ini kita akan mencoba untuk membuat nested_form dari dua model yang saling berelasi dalam sebuah aplikasi rails dengan mengunakan gem 'nested_form'.

INSTALASI

Edit gemfile
gem 'nested_form'

Langkah selanjutnya adalah mengjalankan perintah
$ bundle install

Lalu kita masukan di application.js
//= require jquery_nested_form

PENGUNAAN

Jika kita mempunyai model Order yang mempunyai relasi has_many :line_items, untuk dapat menggunakan gem ini kita harus memasukan accepts_nested_attributes_for :line_items di model Order kita, dan jika menginginkan nested object agar dapat dihapus maka kita dapat menambahkan allow_destroy: true setelahnya.

Berikut adalah ilustrasinya :

order.rb
class Order < ActiveRecord::Base
 has_many :line_items, :dependent => :destroy
  accepts_nested_attributes_for :line_items, allow_destroy: true
end

line_item.rb
class LineItem < ActiveRecord::Base
  belongs_to :order
end

Selanjutnya adalah kita dapat mengunakan nested_form_for untuk dapat menggunakan nesting ini.

<%= nested_form_for @order do |f| %>

Maka dengan demikian kita dapat menggunakan link_to_add dan link_to_remove didalam builder tersebut yang berguna untuk menambahkan dan menghapus nested record, contoh.

<%= f.fields_for :line_items do |li| %>
  <%= li.text_field :item_name %>
  <%= li.text_field  :quantity  %>
  <%= li.text_field  :price  %>
  <%= li.link_to_remove "Remove item" %>
<% end %>
<%= f.link_to_add "Add item", :line_items %>

Satu hal yang tidak boleh kita lupakan untuk Rails 4 adalah penggunaan strong_params, dan kita harus memasukan attributes line_items ke bagian ini di orders_controller.rb agar nested record dari line_items dapat tersimpan di database.

def order_params
 params.require(:order).permit(:order_number, :order_date,        :line_items_attributes => [:id, :item_name, :price, :_destroy])
end

Selamat mencoba dan Happy Coding