rails发送邮件

作者:周星 发布:2017-10-07

     如果你注册了本站,在注册成功后,你的注册邮箱会收到一封来自本网站的邮件供你验证,几乎所有的动态语言都有发送邮件功能,rails也不例外,下面我来分享一下如何配置使用rails来发送邮件。

     rails的Action Mailer模块提供了收发邮件的Model和View,Mailer的工作原理和controller极其相似,它继承自ActionMailer::Base,当我们初始化一个项目时,rails会自动为我们生成app/mailers。原理暂时讲到这里,下面我们一步一步来实现一个发送邮件的功能。

    首先我们需要在 shell 里执行rails g mailer ActivateUser,这个 ActivateUser 是我起的名字,当然你可以根据你自己的需求起一个见名知意的名字。执行了这个命令,我们会发现命令行的输出如下:

➤ rails g mailer ActivateUser
      create  app/mailers/activate_user.rb
      create  app/mailers/application_mailer.rb
      invoke  erb
      create    app/views/activate_user
      create    app/views/layouts/mailer.text.erb
      create    app/views/layouts/mailer.html.erb

     你的命令行可能会输出更多,比如说测试文件,是不是和建立一个 controller 很相似^^,当然你也可以不使用命令创建,而是自己手动添加一个这样的文件,但是一定要确定它继承了ActionMailer::Base。现在我们把注意力都放在这两个文件身上,我们先看 app/mailers/activate_user.rb 这个文件。

    正如对待 controller 一样,我们可以在这个class里面定义action

def user_activate(user)
  @user         = user
  @subject      = "帐号激活"
  @to           = user.email
  mail to: @to, subject: @subject
end

    现在这个 class 包含了发送邮件所需最基本的元素(更多请参考官方文档),mail即是一个邮件的 message(抱歉因能力问题暂时不知如何翻译message),to指定了接受邮件的的地址,subject指定了邮件的主题。这里的user_activate方法需要一个 user 对象作为参数,然后将 use r的 email 字段值作为接受地址。到这里你应该明白的差不多了,但是还有一个疑问,发送的地址和主题都有了,发送的内容是什么呢?

    这个时候我们就要回头看生成的views文件夹了,app/activate_user,我们会发现这里面是空的。我们需要手动创建两个文件:app/activate_mailer/user_activate.html.erb和app/activate_mailer/user_activate.text.erb,这两个文件的前缀要和我们在mailer里定义的action名字匹配,这样我们的action在发送邮件时会自动来寻找我们的view,之所以创建一个html和一个text,是因为有的邮件服务器不支持html格式的邮件。

提示:此邮件是系统自动发出,请不要直接“回复”本邮件。如果您有任何疑问,请发送邮件至 Edward_mjz@hotmail.com
亲爱的<%= @user.name %>
您好!
恭喜您成功注册starzhou.com!!!!
请在浏览器地址栏输入如下地址来激活您的帐号
starzhou.com/users/activate?email=<%= @user.email %>&activate_code=<%= @user.activate_code %>
请妥善保留这封电子邮件
注意:
激活成功的账号才可登陆,您可以评论自己感兴趣的博客,收藏喜欢的博客,还可以对网站进行吐槽。
因为一些不能说的原因,请不要发表敏感信息等,博主在第一时间发现会立即删除且不会给您任何通知。
如果您有任何问题,可以写信给博主 Edward_mjz@hotmail.com
现在开始访问主页:starzhou.com
感谢您的注册和关注,您的支持是我最大的动力,我会继续用心去code,用心去写每一篇博客,用心去研究每一个大家感兴趣的技术。starzhou.com, where better happens
如果您没有申请注册本站,请忽略此邮件。
<%= Date.today.to_s %>

     text格式的内容和html完全一致,只要去掉html里面的标签即可,现在只需在我们需要发送邮件的地方调用mailer里的action,就可以发送邮件了。注:可以指定layout哦。

def create
  @user = User.new(user_params)
  @user.activate_code = SecureRandom.hex 32
  if @user.save
    flash[:success] = '恭喜您注册成功,现在您可畅游所有服务'
    session[:user_id] = @user.id
    ActivateMailer.user_activate(@user).deliver
    redirect_to success_users_path
  else
    render 'new'
  end
end

     上面的代码含有业务逻辑,即用户激活帐号,此内容和本文无关暂且不讲。咦,邮件发送 不成功?那时因为你还缺少更重要的步骤,现在我们把代码写好了,接下来的工作就是对发送邮件进行一些配置。

    发送邮件的配置在 config/environment/development.rb 和 config/environment/production.rb 里,开发即用 development.rb,生产环境则用 production.rb。

    文件里与发送邮件有关的几行配置如下:

config.action_mailer.raise_delivery_errors = false

发送失败时是否报错,默认值为 false

    下面的配置非常重要,它指定了我们邮件发送使用的协议,类型,端口,以及我们邮件服务器的相关信息,你可以使用 gmail/qq 邮箱等作为你 application 的邮件提供商,在此推荐mailgun,每个月可以免费发送1W条邮件,足够我们使用了。

Mywebsite::Application.configure do
  if Settings.present? && Settings.smtp.present?
    config.action_mailer.delivery_method = :smtp
    config.action_mailer.smtp_settings = {
      authentication: :plain,
      address:        Settings.smtp.address,
      port:           Settings.smtp.port,
      domain:         Settings.smtp.domain,
      user_name:      Settings.smtp.user_name,
      password:       Settings.smtp.password,
    }
  end
end

如果线上有自己的域名,需要到DNS服务商那里配置一下我们的mail domain。

到了这里即是见证奇迹的时刻,邮件发送成功了,是不是有一点兴奋呢?

=> #<Mail::Message:70365905150640, Multipart: true, Headers: <Date: Thu, 15 Oct 2015 22:11:56 +0800>, <From: postmaster@xingishere.com>, <To: edward_mjz@hotmail.com>, <Message-ID: <561fb42c95e6e_9cc3fff54c2bbe899625@edwards-MBPR.local.mail>>, <Subject: 帐号激活>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary="--==_mimepart_561fb42c938a3_9cc3fff54c2bbe899540"; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>

更多信息请浏览:http://guides.rubyonrails.org/action_mailer_basics.html

感谢渊格格对此功能提供的技术支持!

支付宝扫码赞助博主


评论(1)

Qq3

六翼第1楼

请问,能不能做到某些邮件用A邮箱发,另一些邮件用B邮箱发呢? 不是改from,而是真的走不同的邮箱。 研究了一阵子好像是不太好弄吧,服务都要重启……

2017-02-07 02:55:17