Ruby on Rails - 发送电子邮件
Ruby on Rails - 邮件发送
Section titled “Ruby on Rails - 邮件发送”Action Mailer 是 Rails 中负责发送和接收邮件的组件。它允许您创建继承自 ApplicationMailer(后者又继承自 ActionMailer::Base)的 Mailer 类来处理邮件投递。
让我们创建一个简单的应用程序 mail_sender_app,来演示如何发送邮件。
$ rails new mail_sender_app$ cd mail_sender_appAction Mailer 配置
Section titled “Action Mailer 配置”Action Mailer 的配置通常在特定环境的文件中完成(例如,config/environments/development.rb, config/environments/production.rb)。
- 设置投递方式:
在
config/environments/development.rb中,指定邮件如何投递。对于开发环境,letter_opener_web是一个很棒的 gem,它可以在浏览器中打开发送的邮件。对于生产环境,您会使用:smtp或 SendGrid、Postmark 等服务。
# Gemfilegem 'letter_opener_web', group: :development# 然后运行: $ bundle installRails.application.configure do # ... 其他配置 ...
config.action_mailer.delivery_method = :letter_opener_web # 用于开发环境 config.action_mailer.perform_deliveries = true # 确保邮件实际发送 config.action_mailer.raise_delivery_errors = true config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } # 对邮件中的链接很重要end- SMTP 设置 (用于生产环境或在开发环境中使用 SMTP): 如果使用 SMTP,请配置地址、端口、域名、用户名和密码等设置。切勿硬编码凭据;请使用 Rails credentials 或环境变量。
# config/environments/production.rb (Gmail SMTP 示例 - 谨慎使用,推荐使用应用专用密码)config.action_mailer.delivery_method = :smtpconfig.action_mailer.smtp_settings = { address: 'smtp.gmail.com', port: 587, domain: 'yourdomain.com', # 或您的应用域名 user_name: ENV['GMAIL_USERNAME'], password: ENV['GMAIL_APP_PASSWORD'], authentication: 'plain', enable_starttls_auto: true}生成 Mailer
Section titled “生成 Mailer”使用 Rails 生成器创建 Mailer。让我们创建一个 UserMailer,包含一个 welcome_email 动作:
$ bin/rails generate mailer UserMailer welcome_email这会创建 app/mailers/user_mailer.rb 和位于 app/views/user_mailer/ 的视图模板文件。
编辑 app/mailers/user_mailer.rb:
class UserMailer < ApplicationMailer default from: 'notifications@example.com' # 默认发件人地址
def welcome_email(user) @user = user @url = 'http://example.com/login' # 邮件中的示例 URL mail(to: @user.email, subject: 'Welcome to Our Awesome Site!') # Rails 会在 app/views/user_mailer/ 目录下查找 welcome_email.html.erb 和 .text.erb 模板 endenddefault from:设置此 Mailer 发送的所有邮件的默认发件人。- 在
welcome_email(user)中,@user使 user 对象在视图模板中可用。 mail(to: ..., subject: ...)发送邮件。如果同时存在 HTML 和文本模板,Rails 会自动创建多部分邮件。
创建邮件视图模板
Section titled “创建邮件视图模板”- HTML 模板 (
app/views/user_mailer/welcome_email.html.erb):
<!DOCTYPE html><html><head> <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body> <h1>Welcome to example.com, <%= @user.name %>!</h1> <p> 您已成功注册 example.com,您的用户名是:<%= @user.login %>。<br> </p> <p> 要登录网站,请点击此链接:<%= link_to '登录', @url %>。 </p> <p>感谢您的加入,祝您有愉快的一天!</p></body></html>- 文本模板 (
app/views/user_mailer/welcome_email.text.erb):
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!调用 Mailer
Section titled “调用 Mailer”通常在特定事件发生后(例如,用户注册),您会从控制器或后台作业中发送邮件。
首先,让我们建立一个简单的 User 模型和控制器:
$ bin/rails generate scaffold User name:string email:string login:string$ bin/rails db:migrate修改 app/controllers/users_controller.rb 中的 create 动作,以发送欢迎邮件:
class UsersController < ApplicationController # ... 其他动作 (index, new, show, edit, update, destroy) ...
# POST /users def create @user = User.new(user_params)
if @user.save # 告诉 UserMailer 在保存后发送欢迎邮件 # .deliver_later 使用 Active Job 异步发送邮件 (推荐) UserMailer.welcome_email(@user).deliver_later
redirect_to @user, notice: '用户创建成功。请检查您的邮箱!' else render :new, status: :unprocessable_entity end end
private def user_params params.require(:user).permit(:name, :email, :login) endend测试邮件投递
Section titled “测试邮件投递”- 启动您的 Rails 服务器:
$ bin/rails s - 如果使用
letter_opener_web,在浏览器中访问http://localhost:3000/letter_opener。 - 访问
http://localhost:3000/users/new创建一个新用户。 - 填写表单并提交。如果成功,邮件应该被“发送”。
- 检查
letter_opener_web(或您配置的邮件投递系统)以查看邮件。
日志文件(log/development.log)也会显示邮件发送的详细信息:
Rendering user_mailer/welcome_email.html.erb within layouts/mailer Rendered user_mailer/welcome_email.html.erb within layouts/mailer (Duration: X.Xms) Rendering user_mailer/welcome_email.text.erb within layouts/mailer Rendered user_mailer/welcome_email.text.erb within layouts/mailer (Duration: X.Xms)UserMailer#welcome_email: processed outbound mail in XXX.XmsSent mail to user@example.com (XXX.Xms)[ActiveJob] Enqueued ActionMailer::MailDeliveryJob (Job ID: xxxxx) to SendGrid(mail)...更多信息:关于附件、内嵌图片和 Mailer 测试等高级主题,请参阅官方的 Action Mailer 基础指南。