Ruby on Rails
ActionMailer
サーチ…
前書き
アクションメーラーを使用すると、メーラーのクラスとビューを使用してアプリケーションから電子メールを送信できます。メーラーはコントローラーと非常によく似ています。彼らはActionMailer :: Baseを継承し、app / mailerに居住し、app / viewsに表示される関連するビューを持っています。
備考
電子メールの送信を非同期的に処理して、Webサーバーを縛らないようにすることをお勧めします。これは、 delayed_job
などのさまざまなサービスを通じて行うことができます。
基本メーラー
この例では、4つの異なるファイルを使用します。
- ユーザーモデル
- ユーザメーラ
- 電子メールのhtmlテンプレート
- 電子メールのプレーンテキストテンプレート
この場合、ユーザーモデルはメーラ内のapproved
メソッドを呼び出し、 approved
たpost
を渡します(モデル内のapproved
メソッドは、コールバックによって、コントローラメソッドから呼び出されるなど)。次に、メーラーは、渡されたpost
(例えば、タイトル)からの情報を使用して、htmlまたはプレーンテキストのいずれかのテンプレートから電子メールを生成します。デフォルトでは、メーラーは、メーラーのメソッドと同じ名前のテンプレートを使用します(メーラー・メソッドとテンプレートの両方に「承認済み」という名前が付いている理由です)。
user_mailer.rb
class UserMailer < ActionMailer::Base
default from: "[email protected]"
def approved(post)
@title = post.title
@user = post.user
mail(to: @user.email, subject: "Your Post was Approved!")
end
end
user.rb
def approved(post)
UserMailer.approved(post)
end
approved.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Post Approved</title>
</head>
<body>
<h2>Congrats <%= @user.name %>! Your post (#<%= @title %>) has been approved!</h2>
<p>We look forward to your future posts!</p>
</body>
</html>
approved.text.erb
Congrats <%= @user.name %>! Your post (#<%= @title %>) has been approved!
We look forward to your future posts!
新しいメーラを生成する
新しいメーラーを生成するには、次のコマンドを入力します
rails generate mailer PostMailer
これにより、 app/mailers/post_mailer.rb
という名前のapp/mailers/post_mailer.rb
空のテンプレートファイルが生成されます
class PostMailer < ApplicationMailer
end
HTML形式とテキスト形式の2つのレイアウトファイルも電子メールビュー用に生成されます。
ジェネレータを使用したくない場合は、独自のメーラを作成することができます。 ActionMailer::Base
から継承していることを確認してください
添付ファイルの追加
ActionMailer
では、ファイルを添付することもできます。
attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
デフォルトでは、添付ファイルはBase64
でエンコードされます。これを変更するには、attachmentsメソッドにハッシュを追加します。
attachments['filename.jpg'] = {
mime_type: 'application/gzip',
encoding: 'SpecialEncoding',
content: encoded_content
}
インラインアタッチメントを追加することもできます
attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')
ActionMailerコールバック
ActionMailerは3つのコールバックをサポートしています
- before_action
- after_action
- around_action
Mailerクラスにこれらを提供する
class UserMailer < ApplicationMailer
after_action :set_delivery_options, :prevent_delivery_to_guests, :set_business_headers
private
キーワードの下にこれらのメソッドを作成します
private
def set_delivery_options
end
def prevent_delivery_to_guests
end
def set_business_headers
end
end
スケジュールされたニュースレターを生成する
ニュースレターモデルを作成する:
rails g model Newsletter name:string email:string subl app/models/newsletter.rb validates :name, presence: true validates :email, presence: true
ニュースレターコントローラを作成する:
rails g controller Newsletters create class NewslettersController < ApplicationController skip_before_action :authenticate_user! before_action :set_newsletter, only: [:destroy] def create @newsletter = Newsletter.create(newsletter_params) if @newsletter.save redirect_to blog_index_path else redirect_to root_path end end private def set_newsletter @newsletter = Newsletter.find(params[:id]) end def newsletter_params params.require(:newsletter).permit(:name, :email) end end
その後、 create.html.erbビューをnex名に変更します。このファイルは、 フッター内に保存される部分ビューに変換されます。名前は_form.html.erbになります 。
名前ファイルを以下から変更: | に: |
---|---|
app / views / newsletters / create.html.erb | app / views / newsletters / _form.html.erb |
その後、ルートを設定します:
subl app/config/routes.rb resources :newsletters
後で、各メールを保存するために使用するフォームを設定する必要があります。
subl app/views/newsletters/_form.html.erb <%= form_for (Newsletter.new) do |f| %> <div class="col-md-12" style="margin: 0 auto; padding: 0;"> <div class="col-md-6" style="padding: 0;"> <%= f.text_field :name, class: 'form-control', placeholder:'Nombre' %> </div> <div class="col-md-6" style="padding: 0;"> <%= f.text_field :email, class: 'form-control', placeholder:'Email' %> </div> </div> <div class="col-md-12" style="margin: 0 auto; padding:0;"> <%= f.submit class:"col-md-12 tran3s s-color-bg hvr-shutter-out-horizontal", style:'border: none; color: white; cursor: pointer; margin: 0.5em auto; padding: 0.75em; width: 100%;' %> </div> <% end %>
その後、フッターに挿入します:
subl app/views/layouts/_footer.html.erb <%= render 'newsletters/form' %>
今、 - letter_opener - をインストールすると、電子メールを送信せずにデフォルトのブラウザでプレビューできます。つまり、開発環境で電子メールの配信を設定する必要はなく、誤って別の人のアドレスにテスト電子メールを送信する心配はありません。
まず、gemを開発環境に追加し、bundleコマンドを実行してインストールします。
subl your_project/Gemfile gem "letter_opener", :group => :development
次に、開発環境で配信方法を設定します。
subl your_project/app/config/environments/development.rb config.action_mailer.delivery_method = :letter_opener
さて、私たちが働くメーラー全体を管理するメーラー構造を作成してください。ターミナル
rails generate mailer UserMailer newsletter_mailer
そして、 UserMailerの中で、 Newsletter Mailerというメソッドを作成しなければなりません 。これは最新のブログ投稿に内部を入れるために作成され、レーキアクションで解雇されます。これまでに作成したブログの構造があると仮定します。
subl your_project/app/mailers/user_mailer.rb class UserMailer '[email protected]' def newsletter_mailer @newsletter = Newsletter.all @post = Post.last(3) emails = @newsletter.collect(&:email).join(", ") mail(to: emails, subject: "Hi, this is a test mail.") end end
その後、 メーラーテンプレートを作成します。
subl your_project/app/views/user_mailer/newsletter_mailer.html.erb <p> Dear Followers: </p> <p> Those are the lastest entries to our blog. We invite you to read and share everything we did on this week. </p> <br/> <table> <% @post.each do |post| %> <%#= link_to blog_url(post) do %> <tr style="display:flex; float:left; clear:both;"> <td style="display:flex; float:left; clear:both; height: 80px; width: 100px;"> <% if post.cover_image.present? %> <%= image_tag post.cover_image.fullsize.url, class:"principal-home-image-slider" %> <%# else %> <%#= image_tag 'http://your_site_project.com' + post.cover_video, class:"principal-home-image-slider" %> <%#= raw(video_embed(post.cover_video)) %> <% end %> </td> <td> <h3> <%= link_to post.title, :controller => "blog", :action => "show", :only_path => false, :id => post.id %> </h3> <p><%= post.subtitle %></p> </td> <td style="display:flex; float:left; clear:both;"> </td> </tr> <%# end %> <% end %> </table>
電子メールを別のプロセスとして送信したいので、電子メールを起動するためのRakeタスクを作成しましょう。 email_tasks.rakeという新しいファイルをRailsアプリケーションのlib / tasksディレクトリに追加します:
touch lib/taks/email_tasks.rake desc 'weekly newsletter email' task weekly_newsletter_email: :environment do UserMailer.newsletter_mailer.deliver! end
send_digest_email ::環境とは、タスクを実行する前にRails環境をロードすることを意味し、タスク内の(UserMailerのような)アプリケーションクラスにアクセスすることができます。
今、rake -Tコマンドを実行すると、新しく作成されたRakeタスクがリストされます。タスクを実行し、電子メールが送信されているかどうかを確認して、すべてをテストします。
メーラメソッドが動作するかどうかをテストするには、rakeコマンドを実行します。
rake weekly_newsletter_email
現時点では、 crontabを使用してスケジューリングできる作業中の作業があります。そこで、cronジョブの作成と配布のための明確な構文を提供するために使用されるWhenever Gemをインストールします。
subl your_project/Gemfile gem 'whenever', require: false
その後、次のコマンドを実行して、あなたのための初期config / schedule.rbファイルを作成します(configフォルダが既にプロジェクトに存在する限り)。
wheneverize . [add] writing `./config/schedule.rb' [done] wheneverized!
スケジュールファイルの中でCRON JOBを作成し、 CRON JOBを指定してmailerメソッドを呼び出すと、選択された時間内にいくつかのタスクを実行する必要があります。このリンクで説明されているように、さまざまな種類の構文を使用できます。
subl your_project/config/schedule.rb every 1.day, :at => '4:30 am' do rake 'weekly_newsletter_email' end
今すぐCronジョブをテストするには、次のコマンドを使用して、CRON構文のターミナル、スケジュールされたジョブを読み込むことができます。
your_project your_mac_user$ whenever 30 4 * * * /bin/bash -l -c 'cd /Users/your_mac_user/Desktop/your_project && RAILS_ENV=production bundle exec rake weekly_newsletter_email --silent'
開発環境でテストを実行するには、 application.rbプリンシパルファイルの次の行を設定して、使用するモデルがどこにあるかをアプリケーションに知らせてください。
subl your_project/config/application.rb config.action_mailer.default_url_options = { :host => "http://localhost:3000/" }
今度はCapistrano V3に新しいCron Jobをサーバー内に保存させ、このタスクの実行をトリガーするトリガーを追加するために、次の要件を追加する必要があります。
subl your_project/Capfile require 'whenever/capistrano'
CRON JOBが環境とアプリケーションの名前について使用する識別子をデプロイメント・ファイルに挿入します 。
subl your_project/config/deploy.rb set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:rails_env)}" }
そして、各ファイルの変更を保存したら、capistrano deployコマンドを実行します:
cap production deploy
そして今あなたの仕事は私が望むもので、このファイルを設定する時間の範囲でメーラーメソッドを実行するために作成され、カレンダー化されました。
ActionMailerインターセプタ
アクションメーラーはインターセプターメソッドにフックを提供します。これらを使用すると、メール配信ライフサイクル中に呼び出されるクラスを登録できます。
インターセプタクラスはdeliver_email(message)メソッドを実装する必要があります。このメソッドは、電子メールが送信される前に呼び出され、電子メールが配信エージェントに当たる前に変更を加えることを可能にします。あなたのクラスは、渡されたMail :: Messageインスタンスに直接必要な修正を加えるべきです。
これは、開発者が実際のユーザーではなく電子メールを送信するのに便利です。
actionmailerインターセプタの登録例:
# config/initializers/override_mail_recipient.rb
if Rails.env.development? or Rails.env.test?
class OverrideMailRecipient
def self.delivering_email(mail)
mail.subject = 'This is dummy subject'
mail.bcc = '[email protected]'
mail.to = '[email protected]'
end
end
ActionMailer::Base.register_interceptor(OverrideMailRecipient)
end