Action Mailer Basics
Bài đăng này đã không được cập nhật trong 7 năm
Introduction
Trong bài này các bạn sẽ cung cấp tất cả những gì cần thiết để có thể gửi và nhận mail từ rails app của bạn.
- Làm thế nào để có thể gửi và nhận mail với rails app
- Làm thế nào để tạo và edit Action mailer class
Send email
Tạo mailer
$ bin/rails generate mailer UserMailer
create app/mailers/user_mailer.rb
create app/mailers/application_mailer.rb
invoke erb
create app/views/user_mailer
create app/views/layouts/mailer.text.erb
create app/views/layouts/mailer.html.erb
invoke test_unit
create test/mailers/user_mailer_test.rb
create test/mailers/previews/user_mailer_preview.rb
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
layout 'mailer'
end
# app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
end
Có thể thấy, bạn có thể tạo mailer giống như là generator khác trong Rails. Mailer được xem giống như là Controller và có thể tạo mailer, tạo thư mục để view và test.
Edit mailer
Mailer thì nó rất giống với Controller. Nó cũng có các method gọi "action" và sử dụng view để xây dựng nội dung, nơi mà controller tạo ra nội dung html để send đến client thì cũng tương tự tại đó mailer sẽ tạo nội dung để gửi qua mail.
class UserMailer < ApplicationMailer
end
Hãy add method gọi welcome mailer welcome_email. Nó sẽ gửi email đến mail đã đăng ký
class UserMailer < ApplicationMailer
default from: 'notifications@example.com'
def welcome_email(user)
@user = user
@url = 'http://example.com/login'
mail(to: @user.email, subject: 'Welcome to My Awesome Site')
end
end
Tạo mailer view
Tạo file welcome_email.html.erb trong app/views/user_mailer/. Nó sẽ trở thành template để view mail và sử dụng format html.
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<h1>Welcome to example.com, <%= @user.name %></h1>
<p>
You have successfully signed up to example.com,
your username is: <%= @user.login %>.<br>
</p>
<p>
To login to the site, just follow this link: <%= @url %>.
</p>
<p>Thanks for joining and have a great day!</p>
</body>
</html>
Welcome to example.com, <%= @user.name %>
===============================================
You have successfully signed up to example.com,
your username is: <%= @user.login %>.
To login to the site, just follow this link: <%= @url %>.
Thanks for joining and have a great day!
Gọi bạn gọi call mail method. Action mail sẽ detect ra 2 template (text & html) và tự động tạo ra multipart/alternative email
Gọi mailer
Mailers thật ra là một cách khác để render một view, thay vì render một view và gửi nó thông qua phương thức HTTP, mailer sẽ gửi nó thông qua "phương thức email". Do đó, sẽ rất tiện cho controller có thể ra lệnh cho Mailer gửi một email khi user được tạo thành công Giờ chúng ta thử cài nào. Đầu tiên cần tạo một scaffold cho model User:
$ bin/rails generate scaffold user name email login
$ bin/rails db:migrate
Sau khi chạy lệnh xong thì chúng ta đã có model User để vọc rồi, chúng ta chỉ cần edit file users_controller.rb để nó bảo UserMailer gửi một email tới thằng user vừa mới được tạo bằng cách sửa hàm create và insert một lời gọi vào trong UserMailer.welcome_mail ngay sau khi save user đó thành công. Action Mailer họat động rất ổn với Active Job nên bạn có thể gửi mail ngay bên ngoài "vòng lặp" request-response, do đó user không cần phải đợi lâu
class UsersController < ApplicationController
# POST /users
# POST /users.json
def create
@user = User.new(params[:user])
respond_to do |format|
if @user.save
# Tell the UserMailer to send a welcome email after save
UserMailer.welcome_email(@user).deliver_later
format.html { redirect_to(@user, notice: 'User was successfully created.') }
format.json { render json: @user, status: :created, location: @user }
else
format.html { render action: 'new' }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
end
Nếu bạn muốn gửi email một cách chuẩn (chẳng hạn từ cronjob) thì chỉ cần gọi hàm deliver_now
class SendWeeklySummary
def run
User.find_each do |user|
UserMailer.weekly_summary(user).deliver_now
end
end
end
Method welcome_email sẽ trả về object ActionMailler::MessageDelivery và nó có tác dụng bảo deliver_now hoặc deliver_later gửi mail đi. Object ActionMailer::MessageDelivery chỉ là một lớp bọc bên ngoài của object Mail::Message. Nếu bạn muốn tìm hiểu sâu hơn hoặc làm cái gì đó với thằng Mail::Message thì có thể sử dụng hàm mesage trong object ActionMailer::MessageDelivery.
Receiving Emails
Trước khi email đến Rails App, bạn cần phải cấu hình hệ thống để forward cái email đó đến App. Vì vậy, để app có thể nhận được mail bạn cần phải: Implement method receive trong mailer Config server để forward email từ chỗ muốn nhận đến app . Dưới đây là ví dụ đơn giản:
class UserMailer < ApplicationMailer
def receive(email)
page = Page.find_by(address: email.to.first)
page.emails.create(
subject: email.subject,
body: email.body
)
if email.has_attachments?
email.attachments.each do |attachment|
page.attachments.create({
file: attachment,
description: email.subject
})
end
end
end
end
Hi vọng thông qua bài viết này, bạn có thể hiểu được phần nào cơ chế gửi và nhận mail trong rails app. Để xem thông tin bài viết hơn, bạn có thể tham khảo link bài viết bên dưới: http://guides.rubyonrails.org/action_mailer_basics.html Thanks for reading!
All rights reserved