Ricerca…


introduzione

Action Mailer ti consente di inviare e-mail dalla tua applicazione utilizzando le classi e le viste del mailer. I mailer funzionano in modo molto simile ai controller. Essi ereditano da ActionMailer :: Base e vivono in app / mailer e hanno viste associate che appaiono in app / view.

Osservazioni

Si consiglia di elaborare l'invio di e-mail in modo asincrono in modo da non legare il server web. Questo può essere fatto attraverso vari servizi come delayed_job .

Mailer di base

Questo esempio utilizza quattro file diversi:

  • Il modello utente
  • Il mailer dell'utente
  • Il modello html per l'email
  • Il modello di testo semplice per l'email

In questo caso, il modello utente chiama il metodo approved nel mailer e passa il post che è stato approvato (il metodo approved nel modello può essere richiamato da un callback, da un metodo controller, ecc.). Quindi, il mailer genera l'email dal modello html o dal testo normale utilizzando le informazioni del post passato (ad esempio il titolo). Per impostazione predefinita, il mailer utilizza il modello con lo stesso nome del metodo nel mailer (motivo per cui sia il metodo mailer che i modelli hanno il nome "approvato").

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!

Generare un nuovo mailer

Per generare un nuovo mailer, immettere il seguente comando

rails generate mailer PostMailer 

Questo genererà un file modello vuoto in app/mailers/post_mailer.rb chiamato PostMailer

class PostMailer < ApplicationMailer
end

Verranno inoltre generati due file di layout per la vista e-mail, uno per il formato html e uno per il formato testo.

Se si preferisce non utilizzare il generatore, è possibile creare i propri mailer. Assicurati che ereditino da ActionMailer::Base

Aggiunta di allegati

ActionMailer consente anche di allegare file.

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

Per impostazione predefinita, gli allegati saranno codificati con Base64 . Per cambiare questo, puoi aggiungere un hash al metodo degli allegati.

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

Puoi anche aggiungere allegati in linea

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

Callback di ActionMailer

ActionMailer supporta tre callback

  • before_action
  • after_action
  • around_action

Forniscili nella tua classe Mailer

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

Quindi creare questi metodi sotto la parola chiave private

private
  def set_delivery_options
  end

  def prevent_delivery_to_guests
  end

  def set_business_headers
  end
end

Generare una Newsletter pianificata

Crea il modello di newsletter :

  rails g model Newsletter name:string email:string

  subl app/models/newsletter.rb

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

Crea il controller della newsletter :

  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

Dopodiché, modifica la vista create.html.erb sul nome nex. Convertiremo questo file e la vista parziale che verrà memorizzata all'interno del piè di pagina . Il nome sarà _form.html.erb .

Cambia il nome del file da: A:
app / views / newsletters / create.html.erb app / views / newsletters / _form.html.erb

Successivamente, imposta i percorsi:

  subl app/config/routes.rb
    
  resources :newsletters

In seguito, dobbiamo impostare il modulo che useremo per salvare ogni mail:

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

E dopo, inserisci sul footer:

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

  <%= render 'newsletters/form' %>

Ora, installa - letter_opener - per poter visualizzare l'anteprima dell'email nel browser predefinito invece di inviarlo. Ciò significa che non è necessario impostare la consegna delle e-mail nel proprio ambiente di sviluppo e non è più necessario preoccuparsi di inviare accidentalmente una e-mail di prova all'indirizzo di qualcun altro.

Per prima cosa aggiungi la gemma al tuo ambiente di sviluppo ed esegui il comando bundle per installarlo.

  subl your_project/Gemfile

  gem "letter_opener", :group => :development

Quindi imposta il metodo di consegna nell'ambiente di sviluppo:

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

  config.action_mailer.delivery_method = :letter_opener

Ora, crea una struttura Mailer per gestire gli interi mailer che lavoreremo. Nel terminale

  rails generate mailer UserMailer newsletter_mailer

E all'interno dell'UtenteMailer , dobbiamo creare un metodo chiamato Newsletter Mailer che verrà creato per contenere all'interno l'ultimo post del blog e verrà attivato con un'azione di rake. Assumeremo che tu avessi una struttura del blog creata prima.

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

Successivamente, crea il modello di posta elettronica :

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>

Poiché desideriamo inviare l'email come processo separato, creiamo un'attività Rake per attivare l'email. Aggiungi un nuovo file chiamato email_tasks.rake alla directory lib / tasks dell'applicazione Rails:

touch lib/taks/email_tasks.rake

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

Send_digest_email:: environment significa caricare l'ambiente Rails prima di eseguire l'attività, in modo da poter accedere alle classi dell'applicazione (come UserMailer) all'interno dell'attività.

Ora, eseguendo il comando rake -T verrà elencata l'attività Rake appena creata. Prova tutto funziona eseguendo l'attività e controllando se l'e-mail è stata inviata o meno.

Per verificare se il metodo mailer funziona, eseguire il comando rake:

  rake weekly_newsletter_email

A questo punto, abbiamo un'attività di rake di lavoro che può essere pianificata usando crontab . Quindi installeremo il Whenever Gem che viene utilizzato per fornire una sintassi chiara per la scrittura e la distribuzione di cron jobs.

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

Successivamente, esegui il comando successivo per creare un file config / schedule.rb iniziale per te (purché la cartella di configurazione sia già presente nel tuo progetto).

  wheneverize .

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

Ora, all'interno del file di pianificazione, dobbiamo creare il nostro CRON JOB e chiamare il metodo mailer nel determinare il LAVORO CRON per eseguire alcune attività senza assistenza e in un intervallo di tempo selezionato. È possibile utilizzare diversi tipi di sintassi come spiegato in questo collegamento .

subl your_project/config/schedule.rb

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

Cron Job Basic Sintassi

Cron Jobs with Whenever

Ora per testare il Cron Job è stato creato con successo possiamo usare il prossimo comando da leggere dal terminale, il nostro lavoro programmato 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'

Ora, per eseguire il test in Development Environment, è consigliabile impostare la riga successiva sul file principal application.rb per consentire all'applicazione di sapere dove si trovano i modelli che utilizzerà.

  subl your_project/config/application.rb

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

Ora per consentire a Capistrano V3 di salvare il nuovo Cron Job all'interno del server e il trigger che ha attivato l'esecuzione di questa attività, dobbiamo aggiungere il prossimo requisito:

  subl your_project/Capfile

  require 'whenever/capistrano'

E inserire nel file di distribuzione l'identificativo che CRON JOB utilizzerà per l' ambiente e il nome dell'applicazione .

subl your_project/config/deploy.rb

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

E pronto, dopo aver salvato le modifiche su ogni file, esegui il comando capistrano deploy:

  cap production deploy

E ora il tuo JOB è stato creato e calendarizzato per eseguire il Metodo Mailer che è quello che voglio e nel tempo che abbiamo impostato su questi file.

ActionMailer Interceptor

Action Mailer fornisce hook nei metodi dell'intercettore. Questi ti consentono di registrare le classi che vengono chiamate durante il ciclo di vita della consegna della posta.

Una classe interceptor deve implementare il metodo: delivering_email (message) che verrà chiamato prima dell'invio dell'e-mail, consentendo di apportare modifiche all'e-mail prima che colpisca gli agenti di consegna. La classe dovrebbe apportare eventuali modifiche necessarie direttamente all'istanza di Mail :: Message passata.

Può essere utile per gli sviluppatori inviare e-mail a se stessi non utenti reali.

Esempio di registrazione di un interceptor di 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow