Selasa, 18 Maret 2014

ActionMailer ( Part 2 )

Pada pertemuan sebelumnya, kita telah membahas topik tentang Action Mailer Basic pada Ruby on Rails. Kali ini kita akan membahas tentang kasus yang lebih advance yang masih berhubungan dengan ActionMailer.

Sebagai contoh disini adalah email akan dikirimkan ke semua user apabila seorang user telah memposting iklan baru.

Pertama, buat model user terlebih dahulu menggunakan devise. Untuk install gem devise, cukup tambahkan
gem 'devise'
pada Gemfile lalu jalankan bundle install di console. Setelah itu jalankan
rails generate devise:install
Baru kita buat model usernya yang telah digenerate dengan devise
rails generate devise user
Lalu jalankan rake db:migrate pada console

Setelah itu kita buat resource untuk post. Agar lebih mudah kita gunakan scaffold. Karena scaffold memudahkan kita untuk menggenerate model, view dan controllers sekaligus.
rails generate scaffold posts
Lalu kita isi tabel post tersebut dengan beberapa kolom, misalkan
class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.integer :price
      t.text :description
      t.integer :user_id
      t.timestamps
    end
  end
end
Buat relasi antara user dan post. Post dimiliki oleh user dan user bisa memiliki banyak posts.
class User < ActiveRecord::Base
  has_many :posts, :dependent => :destroy
end
class Post < ActiveRecord::Base
  belongs_to :user
end
Lalu kita buat method untuk mengirim email ke semua user kecuali user yang memposting iklan tersebut. Email baru akan dikirm setelah user membuat posting iklannya.
Pada file apps/controllers/posts_controllers.rb, include method untuk mengirimkan email setelah post tersebut berhasil disimpan. Misalkan method tersebut diberi nama users_notification. Dalam method tersebut terdapat parameter untuk post dan list user yang akan dikirimkan emailnya. 
class PostsController < ApplicationController
...
def create
    @post = Post.new(params[:post])
    @post.user_id = current_user.id
    respond_to do |format|
      if @post.save
        @users = User.except_this_user(@post)
        unless @users.blank?
          @users.each do |user|
            PostMailer.users_notification(@post, user).deliver
          end
        end
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render json: @post, status: :created, location: @post }
      else
        format.html { render action: "new" }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end
...
end

Untuk list user, kita buat methodnya juga pada model user.rb. List user tersebut adalah semua user kecuali user yang memposting iklan tersebut. 
class User < ActiveRecord::Base
...
  def self.except_this_user(post)
    User.find(:all, :conditions => ["id != ?", post.user_id])
  end
...
end
Setelah itu kita buat method pada post mailernya
class PostMailer < ActionMailer::Base
  default from: "username@email.com"

  def self.users_notification(post, user)
   @post = post
   @user = user
   mail(:to => @user.email, :subject => "Notifikasi iklan baru")
  end

end
Terakhir, kita buat view untuk mailernya. Kita buat view dengan sesuai dengan nama method di mailernya users_notification.html.erb. 
<!DOCTYPE html>
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
  </head>
  <body>
    <p>Hi <%= @user.email%>,<br/>
     <%= @post.user.email %> telah memposting iklan baru :<br/>
     Judul : <%= @post.title %><br/>
     Harga : <%= @post.price %><br/>
     Deskripsi : <%= raw @post.description %><br/>
    </p>
    Terima kasih
  </body>
</html>
Setelah semua selesai kita bisa mencoba ActionMailer tersebut dengan mengentry postingan terbaru.



Email akan terkirim ke semua user secara otomatis setelah post tersebut dibuat.


Selamat mencoba dan happy coding :-)