Ruby on Rails
ActionMailer
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
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