Sök…


Introduktion

Åtgärd Mailer låter dig skicka e-postmeddelanden från din applikation med hjälp av mailer klasser och vyer. Mailers fungerar mycket på samma sätt som kontrollerare. De ärver från ActionMailer :: Base och bor i app / mailers, och de har tillhörande vyer som visas i app / vyer.

Anmärkningar

Det är tillrådligt att behandla skicka e-post asynkront för att inte binda upp din webbserver. Detta kan göras genom olika tjänster som delayed_job .

Grundläggande mailer

Detta exempel använder fyra olika filer:

  • Användarmodellen
  • Användaren mailer
  • HTML-mallen för e-postmeddelandet
  • Vanlig textmall för e-postmeddelandet

I det här fallet anropar användarmodellen den approved metoden i mailaren och passerar post som har godkänts (den approved metoden i modellen kan anropas av ett återuppringning, från en kontrollmetod, etc). Sedan genererar mailaren e-postmeddelandet från antingen html- eller vanlig textmall med informationen från det överförda post (t.ex. titeln). Som standard använder mailaren mallen med samma namn som metoden i mailaren (varför både mailer-metoden och mallarna har namnet "godkänd").

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!

Genererar en ny mailer

För att generera en ny mailer anger du följande kommando

rails generate mailer PostMailer 

Detta genererar en tom mallfil i app/mailers/post_mailer.rb namnet PostMailer

class PostMailer < ApplicationMailer
end

Två layoutfiler genereras också för e-postvyn, en för html-format och en för textformat.

Om du föredrar att inte använda generatoren kan du skapa dina egna mailare. Se till att de ärver från ActionMailer::Base

Lägga till bilagor

ActionMailer tillåter också att bifoga filer.

attachments['filename.jpg'] = File.read('/path/to/filename.jpg')

Som standard kodas bilagor med Base64 . För att ändra detta kan du lägga till en hash till bilagningsmetoden.

attachments['filename.jpg'] = {
  mime_type: 'application/gzip',
  encoding: 'SpecialEncoding',
  content: encoded_content
}

Du kan också lägga till bifogade filer

attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')

ActionMailer-återuppringningar

ActionMailer stöder tre återuppringningar

  • before_action
  • after_action
  • around_action

Ange dessa i din Mailer-klass

class UserMailer < ApplicationMailer
  after_action :set_delivery_options, :prevent_delivery_to_guests, :set_business_headers

Skapa sedan dessa metoder under det private nyckelordet

private
  def set_delivery_options
  end

  def prevent_delivery_to_guests
  end

  def set_business_headers
  end
end

Skapa ett schemalagd nyhetsbrev

Skapa nyhetsbrevsmodellen :

  rails g model Newsletter name:string email:string

  subl app/models/newsletter.rb

  validates :name, presence: true
  validates :email, presence: true

Skapa nyhetsbrevskontrollern :

  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

Ändra sedan create.html.erb- vyn till nex-namnet. Vi konverterar den här filen till en delvis vy som kommer att lagras i Footer . Namnet kommer att vara _form.html.erb .

Ändra namnfil från: Till:
app / visningar / nyhetsbrev / create.html.erb app / visningar / nyhetsbrev / _form.html.erb

Därefter ställer du in rutterna:

  subl app/config/routes.rb
    
  resources :newsletters

Senare måste vi ställa in det formulär vi ska använda för att spara varje post:

  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 %>

Och därefter sätter du på sidfoten:

  subl app/views/layouts/_footer.html.erb

  <%= render 'newsletters/form' %>

Installera nu - letter_opener - för att förhandsgranska e-post i standardwebbläsaren istället för att skicka den. Det betyder att du inte behöver konfigurera e-postleverans i din utvecklingsmiljö och att du inte längre behöver oroa dig för att av misstag skicka ett testmeddelande till någon annans adress.

Lägg först pärla till din utvecklingsmiljö och kör paketkommandot för att installera den.

  subl your_project/Gemfile

  gem "letter_opener", :group => :development

Ställ sedan in leveransmetoden i utvecklingsmiljön:

  subl your_project/app/config/environments/development.rb

  config.action_mailer.delivery_method = :letter_opener

Skapa nu en Mailer-struktur för att hantera alla mailers som vi kommer att arbeta. I terminal

  rails generate mailer UserMailer newsletter_mailer

Och inuti UserMailer måste vi skapa en metod som heter Newsletter Mailer som skapas för att innehålla insidan i det senaste blogginlägget och kommer att avfyras med en rake action. Vi antar att du har skapat en bloggstruktur tidigare.

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

Skapa sedan Mailer-mallen :

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>

Eftersom vi vill skicka e-postmeddelandet som en separat process, låt oss skapa en Rake-uppgift för att avbryta e-postmeddelandet. Lägg till en ny fil som heter e-post_tasks.rake i lib / task-katalogen för din Rails-applikation:

touch lib/taks/email_tasks.rake

desc 'weekly newsletter email'
task weekly_newsletter_email: :environment do
  UserMailer.newsletter_mailer.deliver!
end

Send_digest_email:: miljö betyder att ladda Rails-miljön innan du kör uppgiften, så att du kan komma åt applikationsklasserna (som UserMailer) i uppgiften.

Nu kör kommandorake -T listar den nyligen skapade Rake-uppgiften. Testa allt fungerar genom att köra uppgiften och kontrollera om e-postmeddelandet skickas eller inte.

Kör rake-kommandot för att testa om mailer-metoden fungerar:

  rake weekly_newsletter_email

Just nu har vi en fungerande rake-uppgift som kan planeras med crontab . Så vi kommer att installera Whenever Gem som används för att ge en tydlig syntax för att skriva och distribuera cron-jobb.

subl your_project/Gemfile
  
  gem 'whenever', require: false

Kör sedan nästa kommando för att skapa en initial config / schema.rb-fil för dig (så länge konfigurationsmappen redan finns i ditt projekt).

  wheneverize .

  [add] writing `./config/schedule.rb'
  [done] wheneverized!

Nu, i schemaläggningsfilen, måste vi skapa vår CRON JOB och ringa mailer-metoden inuti att bestämma CRON JOB för att driva vissa uppgifter utan hjälp och inom ett valt tidsintervall. Du kan använda olika typer av syntax som förklaras på den här länken .

subl your_project/config/schedule.rb

every 1.day, :at => '4:30 am' do
  rake 'weekly_newsletter_email'
end

Cron Job Basic Syntax

Cron jobb med när som helst

För att testa Cron Jobb skapades framgångsrikt kan vi använda nästa kommando för att läsa sedan terminal, vårt schemalagda jobb i CRON SYNTAX:

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'

För att köra testet i utvecklingsmiljö är det klokt att ställa in nästa rad på huvudfilen för applikationen.rb för att låta applikationen veta var de modeller den kommer att använda.

  subl your_project/config/application.rb

  config.action_mailer.default_url_options = { :host => "http://localhost:3000/" }

Nu för att låta Capistrano V3 spara det nya Cron Job på servern och utlösaren som kommer att driva upp genomförandet av denna uppgift, måste vi lägga till nästa krav:

  subl your_project/Capfile

  require 'whenever/capistrano'

Och infoga i distribueringsfilen identifieraren som CRON JOB kommer att använda om miljön och namnet på applikationen .

subl your_project/config/deploy.rb

set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:rails_env)}" }

Och redo, efter att ha sparat ändringar på varje fil, kör du kommandot capistrano deploy:

  cap production deploy

Och nu skapades ditt JOB och kalenderades för att köra Mailer-metoden som är vad jag vill ha och inom det tidsintervall vi ställer in för dessa filer.

ActionMailer Interceptor

Åtgärd Mailer tillhandahåller krokar till avlyssningsmetoderna. Dessa låter dig registrera klasser som kallas under livscykeln för postleverans.

En interceptor-klass måste implementera metoden: Deliverying_email (meddelande) som kommer att ringas innan e-postmeddelandet skickas, så att du kan göra ändringar av e-postmeddelandet innan det träffar leveransagenterna. Din klass ska göra nödvändiga ändringar direkt till det som skickas i instansen Mail :: Meddelande.

Det kan vara användbart för utvecklare att skicka e-post till sig själva, inte riktiga användare.

Exempel på att registrera en actionmailers interceptor:

# 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow