サーチ…


前書き

アクションメーラーを使用すると、メーラーのクラスとビューを使用してアプリケーションから電子メールを送信できます。メーラーはコントローラーと非常によく似ています。彼らはActionMailer :: Baseを継承し、app / mailerに居住し、app / viewsに表示される関連するビューを持っています。

備考

電子メールの送信を非同期的に処理して、Webサーバーを縛らないようにすることをお勧めします。これは、 delayed_jobなどのさまざまなサービスを通じて行うことができます。

基本メーラー

この例では、4つの異なるファイルを使用します。

  • ユーザーモデル
  • ユーザメーラ
  • 電子メールのhtmlテンプレート
  • 電子メールのプレーンテキストテンプレート

この場合、ユーザーモデルはメーラ内のapprovedメソッドを呼び出し、 approvedpostを渡します(モデル内の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の仕事

今すぐ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


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow