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 

1 komentar: