Zoeken…


Invoering

Met Action Mailer kunt u e-mails verzenden vanuit uw toepassing met behulp van mailerklassen en views. Mailers werken op dezelfde manier als controllers. Ze erven van ActionMailer :: Base en wonen in app / mailers, en ze hebben bijbehorende weergaven die in app / weergaven verschijnen.

Opmerkingen

Het is raadzaam om het verzenden van e-mail asynchroon te verwerken om uw webserver niet vast te zetten. Dit kan via verschillende services, zoals delayed_job .

Basic Mailer

Dit voorbeeld gebruikt vier verschillende bestanden:

  • Het gebruikersmodel
  • De gebruikersmailer
  • De HTML-sjabloon voor de e-mail
  • De platte tekstsjabloon voor de e-mail

In dit geval roept het gebruikersmodel de approved methode in de mailer aan en geeft deze de goedgekeurde post (de approved methode in het model kan worden opgeroepen door een callback, een controller-methode, enz.). Vervolgens genereert de mailer de e-mail uit de HTML- of platte tekstsjabloon met behulp van de informatie uit het doorgegeven post (bijvoorbeeld de titel). Standaard gebruikt de mailer de sjabloon met dezelfde naam als de methode in de mailer (vandaar dat zowel de mailer-methode als de sjablonen de naam 'goedgekeurd' hebben).

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!

Een nieuwe mailer genereren

Voer de volgende opdracht in om een nieuwe mailer te genereren

rails generate mailer PostMailer 

Dit genereert een leeg sjabloonbestand in app/mailers/post_mailer.rb naam PostMailer

class PostMailer < ApplicationMailer
end

Er worden ook twee lay-outbestanden gegenereerd voor de e-mailweergave, een voor de html-indeling en een voor de tekstindeling.

Als u de generator liever niet gebruikt, kunt u uw eigen mailers maken. Zorg ervoor dat ze erven van ActionMailer::Base

Bijlagen toevoegen

ActionMailer maakt het ook mogelijk om bestanden toe te ActionMailer .

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

Bijlagen worden standaard gecodeerd met Base64 . Om dit te wijzigen, kunt u een hash toevoegen aan de bijlagenmethode.

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

U kunt ook inline bijlagen toevoegen

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

ActionMailer Callbacks

ActionMailer ondersteunt drie callbacks

  • before_action
  • after_action
  • around_action

Lever deze in uw Mailer-klasse

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

Maak vervolgens deze methoden onder het private trefwoord

private
  def set_delivery_options
  end

  def prevent_delivery_to_guests
  end

  def set_business_headers
  end
end

Genereer een geplande nieuwsbrief

Maak het nieuwsbriefmodel :

  rails g model Newsletter name:string email:string

  subl app/models/newsletter.rb

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

Maak de nieuwsbriefcontroller :

  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

Wijzig daarna de weergave create.html.erb in de naam nex. We zullen dit bestand converteren naar een gedeeltelijke weergave die wordt opgeslagen in de voettekst . De naam zal _form.html.erb zijn .

Naambestand wijzigen van: Naar:
app / views / nieuwsbrieven / create.html.erb app / views / nieuwsbrieven / _form.html.erb

Stel daarna de routes in:

  subl app/config/routes.rb
    
  resources :newsletters

Later moeten we het formulier instellen dat we gebruiken om elke e-mail op te slaan:

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

En daarna op de voettekst invoegen:

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

  <%= render 'newsletters/form' %>

Installeer nu de - letter_opener - om een voorbeeld van e-mail te bekijken in de standaardbrowser in plaats van deze te verzenden. Dit betekent dat u geen e-mailbezorging hoeft in te stellen in uw ontwikkelomgeving en dat u zich geen zorgen meer hoeft te maken dat u per ongeluk een test-e-mail naar het adres van iemand anders verzendt.

Voeg eerst de edelsteen toe aan uw ontwikkelomgeving en voer de bundelopdracht uit om deze te installeren.

  subl your_project/Gemfile

  gem "letter_opener", :group => :development

Stel vervolgens de leveringsmethode in de ontwikkelomgeving in:

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

  config.action_mailer.delivery_method = :letter_opener

Maak nu een Mailer-structuur om alle mailers te beheren waaraan we zullen werken. In terminal

  rails generate mailer UserMailer newsletter_mailer

En in de UserMailer moeten we een methode genaamd Nieuwsbrief Mailer maken die zal worden gemaakt om in de laatste blogpost te worden opgenomen en met een rake-actie wordt ontslagen. We gaan ervan uit dat je eerder een blogstructuur hebt gemaakt.

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

Maak daarna de sjabloon Mailer :

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>

Omdat we de e-mail als een afzonderlijk proces willen verzenden, laten we een harktaak maken om de e-mail af te vuren. Voeg een nieuw bestand met de naam email_tasks.rake toe aan de map lib / taken van uw Rails-toepassing:

touch lib/taks/email_tasks.rake

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

De send_digest_email:: omgeving betekent dat de Rails-omgeving wordt geladen voordat de taak wordt uitgevoerd, zodat u toegang hebt tot de toepassingsklassen (zoals UserMailer) binnen de taak.

Als u nu de opdracht rake -T uitvoert, wordt de nieuw gemaakte harktaak weergegeven. Test alles werkt door de taak uit te voeren en te controleren of de e-mail is verzonden of niet.

Voer de opdracht rake uit om te testen of de mailer-methode werkt:

  rake weekly_newsletter_email

Op dit moment hebben we een werkende harktaak die kan worden gepland met crontab . Daarom zullen we de Whenever Gem installeren die wordt gebruikt om een duidelijke syntaxis te bieden voor het schrijven en implementeren van cron-taken.

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

Voer daarna de volgende opdracht uit om een eerste config / schedule.rb-bestand voor u te maken (zolang de map config al in uw project aanwezig is).

  wheneverize .

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

Nu, binnen het planningsbestand, moeten we onze CRON JOB aanmaken en de mailer-methode oproepen om de CRON JOB te bepalen om bepaalde taken zonder hulp en binnen een bepaald tijdsbereik uit te voeren. U kunt verschillende soorten syntaxis gebruiken, zoals wordt uitgelegd op deze link .

subl your_project/config/schedule.rb

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

Cron Job Basic Syntax

Cron Jobs met wanneer dan ook

Nu om te testen of de Cron Job succesvol is gemaakt, kunnen we de volgende opdracht gebruiken om te lezen sinds terminal, onze geplande taak in 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'

Om de test in de ontwikkelomgeving uit te voeren, is het verstandig om de volgende regel in het hoofdbestand van de application.rb in te stellen om de toepassing te laten weten waar de modellen zijn die worden gebruikt.

  subl your_project/config/application.rb

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

Om Capistrano V3 de nieuwe Cron Job binnen de server en de trigger te laten opslaan die de uitvoering van deze taak zal starten, moeten we de volgende vereiste toevoegen:

  subl your_project/Capfile

  require 'whenever/capistrano'

En voeg in het deploy- bestand de identifier in die CRON JOB zal gebruiken over de omgeving en de naam van de applicatie .

subl your_project/config/deploy.rb

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

En klaar, na het opslaan van wijzigingen in elk bestand, voert u de opdracht capistrano deploy uit:

  cap production deploy

En nu is je JOB gemaakt en in een agenda geplaatst om de Mailer-methode uit te voeren, wat ik wil en binnen de tijdsperiode die we voor deze bestanden instellen.

ActionMailer Interceptor

Action Mailer biedt haken in de interceptormethoden. Hiermee kunt u klassen registreren die worden aangeroepen tijdens de levenscyclus van e-mailbezorging.

Een interceptorklasse moet de methode: deliver_email (bericht) implementeren die wordt aangeroepen voordat de e-mail wordt verzonden, zodat u de e-mail kunt wijzigen voordat deze de bezorgers raakt. Uw klas moet de benodigde wijzigingen rechtstreeks in het exemplaar in Mail :: Message aanbrengen.

Het kan handig zijn voor ontwikkelaars om e-mail naar zichzelf te sturen, niet naar echte gebruikers.

Voorbeeld van het registreren van een Actionmailer-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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow