SlideShare ist ein Scribd-Unternehmen logo
1 von 126
Sending Email
With Callbacks
A look at ActionMailer and
the ActiveRecord life cycle
ActionMailer
The email library that comes with Rails
Mailers
Mailers
 Mailers can be used to send email from Rails
Mailers
 Mailers can be used to send email from Rails
   Supports plain text, HTML, and multi-part emails
Mailers
 Mailers can be used to send email from Rails
   Supports plain text, HTML, and multi-part emails
   Supports attachments
Mailers
 Mailers can be used to send email from Rails
   Supports plain text, HTML, and multi-part emails
   Supports attachments
   Multiple send modes including: sendmail and SMTP
Mailers
 Mailers can be used to send email from Rails
   Supports plain text, HTML, and multi-part emails
   Supports attachments
   Multiple send modes including: sendmail and SMTP
 Mailers can also be used to receive emails
Mailers
 Mailers can be used to send email from Rails
   Supports plain text, HTML, and multi-part emails
   Supports attachments
   Multiple send modes including: sendmail and SMTP
 Mailers can also be used to receive emails
   Parses the email data into a Ruby object
M and V, Without the C
M and V, Without the C

Mailer structure is a bit different than other parts of Rails
M and V, Without the C

Mailer structure is a bit different than other parts of Rails
  It’s a model
M and V, Without the C

Mailer structure is a bit different than other parts of Rails
  It’s a model
  But it has views
M and V, Without the C

Mailer structure is a bit different than other parts of Rails
  It’s a model
  But it has views
You can think of it as rendering content for the user, just
not through a browser
Email Example
Email Example

Let’s say I have an application built that requires users
to login to see any content
Email Example

Let’s say I have an application built that requires users
to login to see any content
I have created a User model and built the controller
that allows them to sign-up
Email Example

Let’s say I have an application built that requires users
to login to see any content
I have created a User model and built the controller
that allows them to sign-up
I have also wired up a login system using Authlogic
Email Example

Let’s say I have an application built that requires users
to login to see any content
I have created a User model and built the controller
that allows them to sign-up
I have also wired up a login system using Authlogic
The whole thing works now
A Problem
A Problem


I really need to make sure users give me a valid email
A Problem


I really need to make sure users give me a valid email
Authlogic checks the email address format, but you
can only know an email is valid by sending a message
Adding Authentication
Adding Authentication

When a user signs up:
Adding Authentication

When a user signs up:
  We will send them an email with a special link in it
Adding Authentication

When a user signs up:
  We will send them an email with a special link in it
  Clicking that link will authenticate their address
Adding Authentication

When a user signs up:
  We will send them an email with a special link in it
  Clicking that link will authenticate their address
We won’t allow non-authenticated users access to the
site
Adding Authentication

When a user signs up:
  We will send them an email with a special link in it
  Clicking that link will authenticate their address
We won’t allow non-authenticated users access to the
site
After authentication, their account will work normally
Generate a Mailer
Generate a Mailer
We call script/
generate as usual
                    $ ruby script/generate mailer user_notifier activation
                        exists app/models/
                        create app/views/user_notifier
                        exists test/unit/
                        create test/fixtures/user_notifier
                        create app/models/user_notifier.rb
                        create test/unit/user_notifier_test.rb
                        create app/views/user_notifier/activation.erb
                        create test/fixtures/user_notifier/activation
Generate a Mailer
We call script/
generate as usual
We ask for a mailer   $ ruby script/generate mailer user_notifier activation
                          exists app/models/

and name it               create app/views/user_notifier
                          exists test/unit/
                          create test/fixtures/user_notifier

user_notifier              create app/models/user_notifier.rb
                          create test/unit/user_notifier_test.rb
                          create app/views/user_notifier/activation.erb
                          create test/fixtures/user_notifier/activation
Generate a Mailer
We call script/
generate as usual
We ask for a mailer       $ ruby script/generate mailer user_notifier activation
                              exists app/models/

and name it                   create app/views/user_notifier
                              exists test/unit/
                              create test/fixtures/user_notifier

user_notifier                  create app/models/user_notifier.rb
                              create test/unit/user_notifier_test.rb
                              create app/views/user_notifier/activation.erb
                              create test/fixtures/user_notifier/activation


Optionally, we can also
pass the names of
emails to create
app/models/user_notifier.rb
The generated mailer gets us started
class UserNotifier < ActionMailer::Base
         def activation(sent_at = Time.now)
           subject 'UserNotifier#activation'
           recipients ''
           from      ''
           sent_on sent_at

          body     :greeting => 'Hi,'
         end
        end




app/models/user_notifier.rb
The generated mailer gets us started
class UserNotifier < ActionMailer::Base
         def activation(sent_at = Time.now)
           subject 'UserNotifier#activation'
           recipients ''
           from      ''
           sent_on sent_at

          body     :greeting => 'Hi,'
         end
        end




app/models/user_notifier.rb
The generated mailer gets us started
class UserNotifier < ActionMailer::Base
         def activation(sent_at = Time.now)
           subject 'UserNotifier#activation'
           recipients ''
           from      ''
           sent_on sent_at

          body     :greeting => 'Hi,'
         end
        end




app/models/user_notifier.rb
The generated mailer gets us started
class UserNotifier < ActionMailer::Base
         def activation(sent_at = Time.now)
           subject 'UserNotifier#activation'
           recipients ''
           from      ''
           sent_on sent_at

          body     :greeting => 'Hi,'
         end
        end




app/models/user_notifier.rb
The generated mailer gets us started
class UserNotifier < ActionMailer::Base
         def activation(sent_at = Time.now)
           subject 'UserNotifier#activation'
           recipients ''
           from      ''
           sent_on sent_at

          body     :greeting => 'Hi,'
         end
        end




app/models/user_notifier.rb
The generated mailer gets us started
Customized to our Needs
We will work with a User since that makes sense
for what we are trying to do
class UserNotifier < ActionMailer::Base
         def activation(user)
           subject 'Activate Your Account'
           recipients user.email
           from      'admin@secureapp.com'
           sent_on Time.now

          body     :user => user
         end
        end




Customized to our Needs
We will work with a User since that makes sense
for what we are trying to do
class UserNotifier < ActionMailer::Base
         def activation(user)
           subject 'Activate Your Account'
           recipients user.email
           from      'admin@secureapp.com'
           sent_on Time.now

          body     :user => user
         end
        end




Customized to our Needs
We will work with a User since that makes sense
for what we are trying to do
class UserNotifier < ActionMailer::Base
         def activation(user)
           subject 'Activate Your Account'
           recipients user.email
           from      'admin@secureapp.com'
           sent_on Time.now

          body     :user => user
         end
        end




Customized to our Needs
We will work with a User since that makes sense
for what we are trying to do
class UserNotifier < ActionMailer::Base
         def activation(user)
           subject 'Activate Your Account'
           recipients user.email
           from      'admin@secureapp.com'
           sent_on Time.now

          body     :user => user
         end
        end




Customized to our Needs
We will work with a User since that makes sense
for what we are trying to do
The Email Content
This is the code from
app/views/user_notifier/activation.erb
Welcome to the Secure Application.

Please click the following link to activate your account:

 <%= activate_url(:token => @user.perishable_token, :host => "localhost:3000") %>




The Email Content
This is the code from
app/views/user_notifier/activation.erb
Welcome to the Secure Application.

Please click the following link to activate your account:

 <%= activate_url(:token => @user.perishable_token, :host => "localhost:3000") %>




The Email Content
This is the code from
app/views/user_notifier/activation.erb
Welcome to the Secure Application.

Please click the following link to activate your account:

 <%= activate_url(:token => @user.perishable_token, :host => "localhost:3000") %>




The Email Content
This is the code from
app/views/user_notifier/activation.erb
Welcome to the Secure Application.

Please click the following link to activate your account:

 <%= activate_url(:token => @user.perishable_token, :host => "localhost:3000") %>




The Email Content
This is the code from
app/views/user_notifier/activation.erb
Sending an Email
Sending an Email

You can send an email
from anywhere in the
application
Sending an Email

You can send an email
from anywhere in the
application
                        UserNotifier.deliver_activation(user)
Just call
deliver_EMAIL()
where EMAIL is the
name of the message
Mailers in Production
Mailers in Production

 By default, ActionMailer will try to use sendmail to
 deliver emails in production
Mailers in Production

 By default, ActionMailer will try to use sendmail to
 deliver emails in production
   This works on a lot of servers but is not robust
Mailers in Production

 By default, ActionMailer will try to use sendmail to
 deliver emails in production
   This works on a lot of servers but is not robust
   I recommend setting up a Gmail account and
   configuring ActionMailer to send via SMTP
Mailers in Production

 By default, ActionMailer will try to use sendmail to
 deliver emails in production
   This works on a lot of servers but is not robust
   I recommend setting up a Gmail account and
   configuring ActionMailer to send via SMTP
 You may also wish to shut off ActionMailer’s default
 error raising behavior
Callbacks
Taking actions during the ActiveRecord life cycle
The ActiveRecord Life Cycle
The ActiveRecord Life Cycle
Models have a life cycle
The ActiveRecord Life Cycle
Models have a life cycle
  They are created
The ActiveRecord Life Cycle
Models have a life cycle
  They are created
  Read from the database
The ActiveRecord Life Cycle
Models have a life cycle
  They are created
  Read from the database
  Updated
The ActiveRecord Life Cycle
Models have a life cycle
  They are created
  Read from the database
  Updated
  Destroyed
The ActiveRecord Life Cycle
Models have a life cycle
  They are created
  Read from the database
  Updated
  Destroyed
Callbacks allow us to run code at points in this cycle
The Callback Hooks
The Callback Hooks
after_initialize*
The Callback Hooks
after_initialize*
before_save
The Callback Hooks
after_initialize*
before_save
before_create/update
The Callback Hooks
after_initialize*
before_save
before_create/update
before_validation
The Callback Hooks
after_initialize*
before_save
before_create/update
before_validation
before_validation_on_
create/update
The Callback Hooks
after_initialize*
before_save
before_create/update
before_validation
before_validation_on_
create/update
after_validation
The Callback Hooks
after_initialize*       after_validation_on_cr
                        eate/update
before_save
before_create/update
before_validation
before_validation_on_
create/update
after_validation
The Callback Hooks
after_initialize*       after_validation_on_cr
                        eate/update
before_save
                        after_save
before_create/update
before_validation
before_validation_on_
create/update
after_validation
The Callback Hooks
after_initialize*       after_validation_on_cr
                        eate/update
before_save
                        after_save
before_create/update
                        after_create/update
before_validation
before_validation_on_
create/update
after_validation
The Callback Hooks
after_initialize*       after_validation_on_cr
                        eate/update
before_save
                        after_save
before_create/update
                        after_create/update
before_validation
                        after_find*
before_validation_on_
create/update
after_validation
The Callback Hooks
after_initialize*       after_validation_on_cr
                        eate/update
before_save
                        after_save
before_create/update
                        after_create/update
before_validation
                        after_find*
before_validation_on_
create/update           before_destroy
after_validation
The Callback Hooks
after_initialize*       after_validation_on_cr
                        eate/update
before_save
                        after_save
before_create/update
                        after_create/update
before_validation
                        after_find*
before_validation_on_
create/update           before_destroy
after_validation        after_destroy
Building a Callback
Just choose the type of callback, name a
method, and write a matching Ruby method
class User < ActiveRecord::Base
        acts_as_authentic

        after_create :send_activation_email

        def send_activation_email
         reset_perishable_token!
         UserNotifier.deliver_activation(self)
        end
       end




Building a Callback
Just choose the type of callback, name a
method, and write a matching Ruby method
class User < ActiveRecord::Base
        acts_as_authentic

        after_create :send_activation_email

        def send_activation_email
         reset_perishable_token!
         UserNotifier.deliver_activation(self)
        end
       end




Building a Callback
Just choose the type of callback, name a
method, and write a matching Ruby method
class User < ActiveRecord::Base
        acts_as_authentic

        after_create :send_activation_email

        def send_activation_email
         reset_perishable_token!
         UserNotifier.deliver_activation(self)
        end
       end




Building a Callback
Just choose the type of callback, name a
method, and write a matching Ruby method
class User < ActiveRecord::Base
        acts_as_authentic

        after_create :send_activation_email

        def send_activation_email
         reset_perishable_token!
         UserNotifier.deliver_activation(self)
        end
       end




Building a Callback
Just choose the type of callback, name a
method, and write a matching Ruby method
Not Just for Email
Not Just for Email
 Sending email using callbacks is a common usage
Not Just for Email
 Sending email using callbacks is a common usage
 However, callbacks are a general tool with many uses
Not Just for Email
 Sending email using callbacks is a common usage
 However, callbacks are a general tool with many uses
 For example:
Not Just for Email
 Sending email using callbacks is a common usage
 However, callbacks are a general tool with many uses
 For example:
   You might update an average_review_rating column
   with an after_save on Review
Not Just for Email
 Sending email using callbacks is a common usage
 However, callbacks are a general tool with many uses
 For example:
   You might update an average_review_rating column
   with an after_save on Review
   You might generate a login column from a provided
   email address in a before_validation on User
Completing the Example
We need to make some minor changes and
add a controller to get activation working
Migrating in Activation Fields
Rails migrations are pretty smart and can guess
where you want to add the fields
$ ruby script/generate migration add_activation_fields_to_users
                        perishable_token:string
                        active:boolean




Migrating in Activation Fields
Rails migrations are pretty smart and can guess
where you want to add the fields
$ ruby script/generate migration add_activation_fields_to_users
                        perishable_token:string
                        active:boolean




Migrating in Activation Fields
Rails migrations are pretty smart and can guess
where you want to add the fields
$ ruby script/generate migration add_activation_fields_to_users
                        perishable_token:string
                        active:boolean




Migrating in Activation Fields
Rails migrations are pretty smart and can guess
where you want to add the fields
$ ruby script/generate migration add_activation_fields_to_users
                          perishable_token:string
                          active:boolean


class AddActivationFieldsToUsers < ActiveRecord::Migration
 def self.up
   add_column :users, :perishable_token, :string
   add_column :users, :active, :boolean, :default => false, :null => false
 end

 def self.down
  remove_column :users, :active
  remove_column :users, :perishable_token
 end
end




Migrating in Activation Fields
Rails migrations are pretty smart and can guess
where you want to add the fields
$ ruby script/generate migration add_activation_fields_to_users
                          perishable_token:string
                          active:boolean


class AddActivationFieldsToUsers < ActiveRecord::Migration
 def self.up
   add_column :users, :perishable_token, :string
   add_column :users, :active, :boolean, :default => false, :null => false
 end

 def self.down
  remove_column :users, :active
  remove_column :users, :perishable_token
 end
end




Migrating in Activation Fields
Rails migrations are pretty smart and can guess
where you want to add the fields
$ ruby script/generate migration add_activation_fields_to_users
                          perishable_token:string
                          active:boolean


class AddActivationFieldsToUsers < ActiveRecord::Migration
 def self.up
   add_column :users, :perishable_token, :string
   add_column :users, :active, :boolean, :default => false, :null => false
 end

 def self.down
  remove_column :users, :active
  remove_column :users, :perishable_token
 end
end


                                    $ rake db:migrate




Migrating in Activation Fields
Rails migrations are pretty smart and can guess
where you want to add the fields
Adding Activations
We look the user up by token, activate them,
and log them in
$ ruby script/generate controller activations




Adding Activations
We look the user up by token, activate them,
and log them in
$ ruby script/generate controller activations


   class ActivationsController < ApplicationController
    def create
      if @user = User.find_using_perishable_token(params[:token])
        @user.active = true      # activate the user
        @user.save
        UserSession.create(@user) # log them in
        flash[:notice] = "User activated."
      else
        flash[:error] = "User not found."
      end
      redirect_to root_path
    end
   end




Adding Activations
We look the user up by token, activate them,
and log them in
$ ruby script/generate controller activations


   class ActivationsController < ApplicationController
    def create
      if @user = User.find_using_perishable_token(params[:token])
        @user.active = true      # activate the user
        @user.save
        UserSession.create(@user) # log them in
        flash[:notice] = "User activated."
      else
        flash[:error] = "User not found."
      end
      redirect_to root_path
    end
   end




Adding Activations
We look the user up by token, activate them,
and log them in
$ ruby script/generate controller activations


   class ActivationsController < ApplicationController
    def create
      if @user = User.find_using_perishable_token(params[:token])
        @user.active = true      # activate the user
        @user.save
        UserSession.create(@user) # log them in
        flash[:notice] = "User activated."
      else
        flash[:error] = "User not found."
      end
      redirect_to root_path
    end
   end




Adding Activations
We look the user up by token, activate them,
and log them in
$ ruby script/generate controller activations


   class ActivationsController < ApplicationController
    def create
      if @user = User.find_using_perishable_token(params[:token])
        @user.active = true      # activate the user
        @user.save
        UserSession.create(@user) # log them in
        flash[:notice] = "User activated."
      else
        flash[:error] = "User not found."
      end
      redirect_to root_path
    end
   end




Adding Activations
We look the user up by token, activate them,
and log them in
Email Routing
We can’t make an email link POST,
so I created a custom route for the action
ActionController::Routing::Routes.draw do |map|
 map.resources :users
 map.resource :user_session

 map.login "login", :controller => "user_sessions", :action => "new"
 map.logout "logout", :controller => "user_sessions", :action => "destroy"

 map.activate "activate/:token", :controller => "activations",
                      :action   => "create"

 map.root :controller => "home"

 map.connect ':controller/:action/:id'
 map.connect ':controller/:action/:id.:format'
end




Email Routing
We can’t make an email link POST,
so I created a custom route for the action
ActionController::Routing::Routes.draw do |map|
 map.resources :users
 map.resource :user_session

 map.login "login", :controller => "user_sessions", :action => "new"
 map.logout "logout", :controller => "user_sessions", :action => "destroy"

 map.activate "activate/:token", :controller => "activations",
                      :action   => "create"

 map.root :controller => "home"

 map.connect ':controller/:action/:id'
 map.connect ':controller/:action/:id.:format'
end




Email Routing
We can’t make an email link POST,
so I created a custom route for the action
The Old Sign-up
Our old controller logs them in as they are
created and we can’t have that
class UsersController < ApplicationController
      def new
        @user = User.new
      end

      def create
       @user = User.new(params[:user])
       if @user.save
         flash[:notice] = "Welcome!"
         redirect_to root_path
       else
         flash.now[:error] = "Sign-up could not be completed."
         render :action => :new
       end
      end
     end




The Old Sign-up
Our old controller logs them in as they are
created and we can’t have that
class UsersController < ApplicationController
      def new
        @user = User.new
      end

      def create
       @user = User.new(params[:user])
       if @user.save
         flash[:notice] = "Welcome!"
         redirect_to root_path
       else
         flash.now[:error] = "Sign-up could not be completed."
         render :action => :new
       end
      end
     end




The Old Sign-up
Our old controller logs them in as they are
created and we can’t have that
class UsersController < ApplicationController
      def new
        @user = User.new
      end

      def create
       @user = User.new(params[:user])
       if @user.save
         flash[:notice] = "Welcome!"
         redirect_to root_path
       else
         flash.now[:error] = "Sign-up could not be completed."
         render :action => :new
       end
      end
     end




The Old Sign-up
Our old controller logs them in as they are
created and we can’t have that
Creation Without Login
Now we don’t log them in and we tell them to
check their email
class UsersController < ApplicationController
 def new
   @user = User.new
 end

 def create
  @user = User.new(params[:user])
  if @user.save_without_session_maintenance
    flash[:notice] = "Please check your email to activate your account."
    redirect_to login_path
  else
    flash.now[:error] = "Sign-up could not be completed."
    render :action => :new
  end
 end
end




Creation Without Login
Now we don’t log them in and we tell them to
check their email
class UsersController < ApplicationController
 def new
   @user = User.new
 end

 def create
  @user = User.new(params[:user])
  if @user.save_without_session_maintenance
    flash[:notice] = "Please check your email to activate your account."
    redirect_to login_path
  else
    flash.now[:error] = "Sign-up could not be completed."
    render :action => :new
  end
 end
end




Creation Without Login
Now we don’t log them in and we tell them to
check their email
class UsersController < ApplicationController
 def new
   @user = User.new
 end

 def create
  @user = User.new(params[:user])
  if @user.save_without_session_maintenance
    flash[:notice] = "Please check your email to activate your account."
    redirect_to login_path
  else
    flash.now[:error] = "Sign-up could not be completed."
    render :action => :new
  end
 end
end




Creation Without Login
Now we don’t log them in and we tell them to
check their email
Activations in Action
Let’s see what we have created
Signing Up
I can create a new user with
my email address and desired password
Signing Up
I can create a new user with
my email address and desired password
Time to Check Email
I wasn’t logged in, as planned
Time to Check Email
I wasn’t logged in, as planned
Can’t Login Yet
I can’t login yet either,
since my account isn’t active yet
Can’t Login Yet
I can’t login yet either,
since my account isn’t active yet
log/development.rb
In development mode, emails are printed to
the log file (clear logs with: rake log:clear)
Sent mail to james@graysoftinc.com

   Date: Sun, 7 Mar 2010 15:10:11 -0600
   From: admin@secureapp.com
   To: james@graysoftinc.com
   Subject: Activate Your Account
   Mime-Version: 1.0
   Content-Type: text/plain; charset=utf-8

   Welcome to the Secure Application.

   Please click the following link to activate your account:

    http://localhost:3000/activate/5HkeFFwiInKfjA4x25q9




log/development.rb
In development mode, emails are printed to
the log file (clear logs with: rake log:clear)
Activated and Logged In
Visiting the URL completes the process
Activated and Logged In
Visiting the URL completes the process
Questions?
User Emails Lab
Your book has instructions for how to add
email notifications to your application

Weitere ähnliche Inhalte

Was ist angesagt?

Cutting the Fat by Tiffany Conroy
Cutting the Fat by Tiffany ConroyCutting the Fat by Tiffany Conroy
Cutting the Fat by Tiffany ConroyCodemotion
 
Codemotion Rome 2015 Bluemix Lab Tutorial
Codemotion Rome 2015 Bluemix Lab TutorialCodemotion Rome 2015 Bluemix Lab Tutorial
Codemotion Rome 2015 Bluemix Lab Tutorialgjuljo
 
Collecting a Image Label from Crowds Using Amazon Mechanical Turk
Collecting a Image Label from Crowds Using Amazon Mechanical TurkCollecting a Image Label from Crowds Using Amazon Mechanical Turk
Collecting a Image Label from Crowds Using Amazon Mechanical TurkJanet Huang
 
Resources and relationships at front-end
Resources and relationships at front-endResources and relationships at front-end
Resources and relationships at front-endWingify Engineering
 
Introduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.jsIntroduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.jsReturn on Intelligence
 
How React Native Appium and me made each other shine
How React Native Appium and me made each other shineHow React Native Appium and me made each other shine
How React Native Appium and me made each other shineWim Selles
 
AngularJs presentation
AngularJs presentation AngularJs presentation
AngularJs presentation Phan Tuan
 

Was ist angesagt? (9)

Cutting the Fat by Tiffany Conroy
Cutting the Fat by Tiffany ConroyCutting the Fat by Tiffany Conroy
Cutting the Fat by Tiffany Conroy
 
Codemotion Rome 2015 Bluemix Lab Tutorial
Codemotion Rome 2015 Bluemix Lab TutorialCodemotion Rome 2015 Bluemix Lab Tutorial
Codemotion Rome 2015 Bluemix Lab Tutorial
 
Collecting a Image Label from Crowds Using Amazon Mechanical Turk
Collecting a Image Label from Crowds Using Amazon Mechanical TurkCollecting a Image Label from Crowds Using Amazon Mechanical Turk
Collecting a Image Label from Crowds Using Amazon Mechanical Turk
 
Resources and relationships at front-end
Resources and relationships at front-endResources and relationships at front-end
Resources and relationships at front-end
 
Don't Settle for Poor Names
Don't Settle for Poor NamesDon't Settle for Poor Names
Don't Settle for Poor Names
 
Introduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.jsIntroduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.js
 
How React Native Appium and me made each other shine
How React Native Appium and me made each other shineHow React Native Appium and me made each other shine
How React Native Appium and me made each other shine
 
Designing rest with raml part3
Designing rest with raml part3Designing rest with raml part3
Designing rest with raml part3
 
AngularJs presentation
AngularJs presentation AngularJs presentation
AngularJs presentation
 

Ähnlich wie Sending Email with Rails

How to implement multiple authentication guards in laravel 8
How to implement multiple authentication guards in laravel 8How to implement multiple authentication guards in laravel 8
How to implement multiple authentication guards in laravel 8Katy Slemon
 
Laravel 8 events and listeners with example
Laravel 8 events and listeners with exampleLaravel 8 events and listeners with example
Laravel 8 events and listeners with exampleKaty Slemon
 
Laravel mail example how to send an email using markdown template in laravel 8
Laravel mail example how to send an email using markdown template in laravel 8Laravel mail example how to send an email using markdown template in laravel 8
Laravel mail example how to send an email using markdown template in laravel 8Katy Slemon
 
Build restful ap is with python and flask
Build restful ap is with python and flaskBuild restful ap is with python and flask
Build restful ap is with python and flaskJeetendra singh
 
More to RoC weibo
More to RoC weiboMore to RoC weibo
More to RoC weiboshaokun
 
Node mailer example how to send email using nodemailer with gmail &amp; mailtrap
Node mailer example how to send email using nodemailer with gmail &amp; mailtrapNode mailer example how to send email using nodemailer with gmail &amp; mailtrap
Node mailer example how to send email using nodemailer with gmail &amp; mailtrapKaty Slemon
 
RoR 101: Session 5
RoR 101: Session 5RoR 101: Session 5
RoR 101: Session 5Rory Gianni
 
Transformando os pepinos do cliente no código de testes da sua aplicação
Transformando os pepinos do cliente no código de testes da sua aplicaçãoTransformando os pepinos do cliente no código de testes da sua aplicação
Transformando os pepinos do cliente no código de testes da sua aplicaçãoRodrigo Urubatan
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)Cogapp
 
Task scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorialTask scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorialKaty Slemon
 
How to implement email functionalities with Mailjet api
How to implement email functionalities with Mailjet apiHow to implement email functionalities with Mailjet api
How to implement email functionalities with Mailjet apiE Boisgontier
 
Introduce cucumber
Introduce cucumberIntroduce cucumber
Introduce cucumberBachue Zhou
 
Associations & JavaScript
Associations & JavaScriptAssociations & JavaScript
Associations & JavaScriptJoost Elfering
 

Ähnlich wie Sending Email with Rails (20)

How to implement multiple authentication guards in laravel 8
How to implement multiple authentication guards in laravel 8How to implement multiple authentication guards in laravel 8
How to implement multiple authentication guards in laravel 8
 
Laravel 8 events and listeners with example
Laravel 8 events and listeners with exampleLaravel 8 events and listeners with example
Laravel 8 events and listeners with example
 
Active record(1)
Active record(1)Active record(1)
Active record(1)
 
Laravel mail example how to send an email using markdown template in laravel 8
Laravel mail example how to send an email using markdown template in laravel 8Laravel mail example how to send an email using markdown template in laravel 8
Laravel mail example how to send an email using markdown template in laravel 8
 
Build restful ap is with python and flask
Build restful ap is with python and flaskBuild restful ap is with python and flask
Build restful ap is with python and flask
 
More to RoC weibo
More to RoC weiboMore to RoC weibo
More to RoC weibo
 
Rails introduction
Rails introductionRails introduction
Rails introduction
 
Node mailer example how to send email using nodemailer with gmail &amp; mailtrap
Node mailer example how to send email using nodemailer with gmail &amp; mailtrapNode mailer example how to send email using nodemailer with gmail &amp; mailtrap
Node mailer example how to send email using nodemailer with gmail &amp; mailtrap
 
RoR 101: Session 5
RoR 101: Session 5RoR 101: Session 5
RoR 101: Session 5
 
Transformando os pepinos do cliente no código de testes da sua aplicação
Transformando os pepinos do cliente no código de testes da sua aplicaçãoTransformando os pepinos do cliente no código de testes da sua aplicação
Transformando os pepinos do cliente no código de testes da sua aplicação
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
 
Task scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorialTask scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorial
 
18.register login
18.register login18.register login
18.register login
 
How to implement email functionalities with Mailjet api
How to implement email functionalities with Mailjet apiHow to implement email functionalities with Mailjet api
How to implement email functionalities with Mailjet api
 
Messaging APIs of RingCentral
Messaging APIs of RingCentralMessaging APIs of RingCentral
Messaging APIs of RingCentral
 
Introduce cucumber
Introduce cucumberIntroduce cucumber
Introduce cucumber
 
Associations & JavaScript
Associations & JavaScriptAssociations & JavaScript
Associations & JavaScript
 
Devise and Rails
Devise and RailsDevise and Rails
Devise and Rails
 

Mehr von James Gray

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A KeynoteJames Gray
 
Regular expressions
Regular expressionsRegular expressions
Regular expressionsJames Gray
 
Counting on God
Counting on GodCounting on God
Counting on GodJames Gray
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your MindJames Gray
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)James Gray
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHubJames Gray
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in RailsJames Gray
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And RenderingJames Gray
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in RailsJames Gray
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersJames Gray
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails InterfaceJames Gray
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model BasicsJames Gray
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on RailsJames Gray
 

Mehr von James Gray (18)

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A Keynote
 
I Doubt That!
I Doubt That!I Doubt That!
I Doubt That!
 
Regular expressions
Regular expressionsRegular expressions
Regular expressions
 
Counting on God
Counting on GodCounting on God
Counting on God
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your Mind
 
Unblocked
UnblockedUnblocked
Unblocked
 
Module Magic
Module MagicModule Magic
Module Magic
 
API Design
API DesignAPI Design
API Design
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHub
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in Rails
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And Rendering
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in Rails
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and Controllers
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails Interface
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model Basics
 
Ruby
RubyRuby
Ruby
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on Rails
 

Kürzlich hochgeladen

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 

Kürzlich hochgeladen (20)

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 

Sending Email with Rails

  • 1. Sending Email With Callbacks A look at ActionMailer and the ActiveRecord life cycle
  • 2. ActionMailer The email library that comes with Rails
  • 4. Mailers Mailers can be used to send email from Rails
  • 5. Mailers Mailers can be used to send email from Rails Supports plain text, HTML, and multi-part emails
  • 6. Mailers Mailers can be used to send email from Rails Supports plain text, HTML, and multi-part emails Supports attachments
  • 7. Mailers Mailers can be used to send email from Rails Supports plain text, HTML, and multi-part emails Supports attachments Multiple send modes including: sendmail and SMTP
  • 8. Mailers Mailers can be used to send email from Rails Supports plain text, HTML, and multi-part emails Supports attachments Multiple send modes including: sendmail and SMTP Mailers can also be used to receive emails
  • 9. Mailers Mailers can be used to send email from Rails Supports plain text, HTML, and multi-part emails Supports attachments Multiple send modes including: sendmail and SMTP Mailers can also be used to receive emails Parses the email data into a Ruby object
  • 10. M and V, Without the C
  • 11. M and V, Without the C Mailer structure is a bit different than other parts of Rails
  • 12. M and V, Without the C Mailer structure is a bit different than other parts of Rails It’s a model
  • 13. M and V, Without the C Mailer structure is a bit different than other parts of Rails It’s a model But it has views
  • 14. M and V, Without the C Mailer structure is a bit different than other parts of Rails It’s a model But it has views You can think of it as rendering content for the user, just not through a browser
  • 16. Email Example Let’s say I have an application built that requires users to login to see any content
  • 17. Email Example Let’s say I have an application built that requires users to login to see any content I have created a User model and built the controller that allows them to sign-up
  • 18. Email Example Let’s say I have an application built that requires users to login to see any content I have created a User model and built the controller that allows them to sign-up I have also wired up a login system using Authlogic
  • 19. Email Example Let’s say I have an application built that requires users to login to see any content I have created a User model and built the controller that allows them to sign-up I have also wired up a login system using Authlogic The whole thing works now
  • 21. A Problem I really need to make sure users give me a valid email
  • 22. A Problem I really need to make sure users give me a valid email Authlogic checks the email address format, but you can only know an email is valid by sending a message
  • 25. Adding Authentication When a user signs up: We will send them an email with a special link in it
  • 26. Adding Authentication When a user signs up: We will send them an email with a special link in it Clicking that link will authenticate their address
  • 27. Adding Authentication When a user signs up: We will send them an email with a special link in it Clicking that link will authenticate their address We won’t allow non-authenticated users access to the site
  • 28. Adding Authentication When a user signs up: We will send them an email with a special link in it Clicking that link will authenticate their address We won’t allow non-authenticated users access to the site After authentication, their account will work normally
  • 30. Generate a Mailer We call script/ generate as usual $ ruby script/generate mailer user_notifier activation exists app/models/ create app/views/user_notifier exists test/unit/ create test/fixtures/user_notifier create app/models/user_notifier.rb create test/unit/user_notifier_test.rb create app/views/user_notifier/activation.erb create test/fixtures/user_notifier/activation
  • 31. Generate a Mailer We call script/ generate as usual We ask for a mailer $ ruby script/generate mailer user_notifier activation exists app/models/ and name it create app/views/user_notifier exists test/unit/ create test/fixtures/user_notifier user_notifier create app/models/user_notifier.rb create test/unit/user_notifier_test.rb create app/views/user_notifier/activation.erb create test/fixtures/user_notifier/activation
  • 32. Generate a Mailer We call script/ generate as usual We ask for a mailer $ ruby script/generate mailer user_notifier activation exists app/models/ and name it create app/views/user_notifier exists test/unit/ create test/fixtures/user_notifier user_notifier create app/models/user_notifier.rb create test/unit/user_notifier_test.rb create app/views/user_notifier/activation.erb create test/fixtures/user_notifier/activation Optionally, we can also pass the names of emails to create
  • 34. class UserNotifier < ActionMailer::Base def activation(sent_at = Time.now) subject 'UserNotifier#activation' recipients '' from '' sent_on sent_at body :greeting => 'Hi,' end end app/models/user_notifier.rb The generated mailer gets us started
  • 35. class UserNotifier < ActionMailer::Base def activation(sent_at = Time.now) subject 'UserNotifier#activation' recipients '' from '' sent_on sent_at body :greeting => 'Hi,' end end app/models/user_notifier.rb The generated mailer gets us started
  • 36. class UserNotifier < ActionMailer::Base def activation(sent_at = Time.now) subject 'UserNotifier#activation' recipients '' from '' sent_on sent_at body :greeting => 'Hi,' end end app/models/user_notifier.rb The generated mailer gets us started
  • 37. class UserNotifier < ActionMailer::Base def activation(sent_at = Time.now) subject 'UserNotifier#activation' recipients '' from '' sent_on sent_at body :greeting => 'Hi,' end end app/models/user_notifier.rb The generated mailer gets us started
  • 38. class UserNotifier < ActionMailer::Base def activation(sent_at = Time.now) subject 'UserNotifier#activation' recipients '' from '' sent_on sent_at body :greeting => 'Hi,' end end app/models/user_notifier.rb The generated mailer gets us started
  • 39. Customized to our Needs We will work with a User since that makes sense for what we are trying to do
  • 40. class UserNotifier < ActionMailer::Base def activation(user) subject 'Activate Your Account' recipients user.email from 'admin@secureapp.com' sent_on Time.now body :user => user end end Customized to our Needs We will work with a User since that makes sense for what we are trying to do
  • 41. class UserNotifier < ActionMailer::Base def activation(user) subject 'Activate Your Account' recipients user.email from 'admin@secureapp.com' sent_on Time.now body :user => user end end Customized to our Needs We will work with a User since that makes sense for what we are trying to do
  • 42. class UserNotifier < ActionMailer::Base def activation(user) subject 'Activate Your Account' recipients user.email from 'admin@secureapp.com' sent_on Time.now body :user => user end end Customized to our Needs We will work with a User since that makes sense for what we are trying to do
  • 43. class UserNotifier < ActionMailer::Base def activation(user) subject 'Activate Your Account' recipients user.email from 'admin@secureapp.com' sent_on Time.now body :user => user end end Customized to our Needs We will work with a User since that makes sense for what we are trying to do
  • 44. The Email Content This is the code from app/views/user_notifier/activation.erb
  • 45. Welcome to the Secure Application. Please click the following link to activate your account: <%= activate_url(:token => @user.perishable_token, :host => "localhost:3000") %> The Email Content This is the code from app/views/user_notifier/activation.erb
  • 46. Welcome to the Secure Application. Please click the following link to activate your account: <%= activate_url(:token => @user.perishable_token, :host => "localhost:3000") %> The Email Content This is the code from app/views/user_notifier/activation.erb
  • 47. Welcome to the Secure Application. Please click the following link to activate your account: <%= activate_url(:token => @user.perishable_token, :host => "localhost:3000") %> The Email Content This is the code from app/views/user_notifier/activation.erb
  • 48. Welcome to the Secure Application. Please click the following link to activate your account: <%= activate_url(:token => @user.perishable_token, :host => "localhost:3000") %> The Email Content This is the code from app/views/user_notifier/activation.erb
  • 50. Sending an Email You can send an email from anywhere in the application
  • 51. Sending an Email You can send an email from anywhere in the application UserNotifier.deliver_activation(user) Just call deliver_EMAIL() where EMAIL is the name of the message
  • 53. Mailers in Production By default, ActionMailer will try to use sendmail to deliver emails in production
  • 54. Mailers in Production By default, ActionMailer will try to use sendmail to deliver emails in production This works on a lot of servers but is not robust
  • 55. Mailers in Production By default, ActionMailer will try to use sendmail to deliver emails in production This works on a lot of servers but is not robust I recommend setting up a Gmail account and configuring ActionMailer to send via SMTP
  • 56. Mailers in Production By default, ActionMailer will try to use sendmail to deliver emails in production This works on a lot of servers but is not robust I recommend setting up a Gmail account and configuring ActionMailer to send via SMTP You may also wish to shut off ActionMailer’s default error raising behavior
  • 57. Callbacks Taking actions during the ActiveRecord life cycle
  • 59. The ActiveRecord Life Cycle Models have a life cycle
  • 60. The ActiveRecord Life Cycle Models have a life cycle They are created
  • 61. The ActiveRecord Life Cycle Models have a life cycle They are created Read from the database
  • 62. The ActiveRecord Life Cycle Models have a life cycle They are created Read from the database Updated
  • 63. The ActiveRecord Life Cycle Models have a life cycle They are created Read from the database Updated Destroyed
  • 64. The ActiveRecord Life Cycle Models have a life cycle They are created Read from the database Updated Destroyed Callbacks allow us to run code at points in this cycle
  • 72. The Callback Hooks after_initialize* after_validation_on_cr eate/update before_save before_create/update before_validation before_validation_on_ create/update after_validation
  • 73. The Callback Hooks after_initialize* after_validation_on_cr eate/update before_save after_save before_create/update before_validation before_validation_on_ create/update after_validation
  • 74. The Callback Hooks after_initialize* after_validation_on_cr eate/update before_save after_save before_create/update after_create/update before_validation before_validation_on_ create/update after_validation
  • 75. The Callback Hooks after_initialize* after_validation_on_cr eate/update before_save after_save before_create/update after_create/update before_validation after_find* before_validation_on_ create/update after_validation
  • 76. The Callback Hooks after_initialize* after_validation_on_cr eate/update before_save after_save before_create/update after_create/update before_validation after_find* before_validation_on_ create/update before_destroy after_validation
  • 77. The Callback Hooks after_initialize* after_validation_on_cr eate/update before_save after_save before_create/update after_create/update before_validation after_find* before_validation_on_ create/update before_destroy after_validation after_destroy
  • 78. Building a Callback Just choose the type of callback, name a method, and write a matching Ruby method
  • 79. class User < ActiveRecord::Base acts_as_authentic after_create :send_activation_email def send_activation_email reset_perishable_token! UserNotifier.deliver_activation(self) end end Building a Callback Just choose the type of callback, name a method, and write a matching Ruby method
  • 80. class User < ActiveRecord::Base acts_as_authentic after_create :send_activation_email def send_activation_email reset_perishable_token! UserNotifier.deliver_activation(self) end end Building a Callback Just choose the type of callback, name a method, and write a matching Ruby method
  • 81. class User < ActiveRecord::Base acts_as_authentic after_create :send_activation_email def send_activation_email reset_perishable_token! UserNotifier.deliver_activation(self) end end Building a Callback Just choose the type of callback, name a method, and write a matching Ruby method
  • 82. class User < ActiveRecord::Base acts_as_authentic after_create :send_activation_email def send_activation_email reset_perishable_token! UserNotifier.deliver_activation(self) end end Building a Callback Just choose the type of callback, name a method, and write a matching Ruby method
  • 83. Not Just for Email
  • 84. Not Just for Email Sending email using callbacks is a common usage
  • 85. Not Just for Email Sending email using callbacks is a common usage However, callbacks are a general tool with many uses
  • 86. Not Just for Email Sending email using callbacks is a common usage However, callbacks are a general tool with many uses For example:
  • 87. Not Just for Email Sending email using callbacks is a common usage However, callbacks are a general tool with many uses For example: You might update an average_review_rating column with an after_save on Review
  • 88. Not Just for Email Sending email using callbacks is a common usage However, callbacks are a general tool with many uses For example: You might update an average_review_rating column with an after_save on Review You might generate a login column from a provided email address in a before_validation on User
  • 89. Completing the Example We need to make some minor changes and add a controller to get activation working
  • 90. Migrating in Activation Fields Rails migrations are pretty smart and can guess where you want to add the fields
  • 91. $ ruby script/generate migration add_activation_fields_to_users perishable_token:string active:boolean Migrating in Activation Fields Rails migrations are pretty smart and can guess where you want to add the fields
  • 92. $ ruby script/generate migration add_activation_fields_to_users perishable_token:string active:boolean Migrating in Activation Fields Rails migrations are pretty smart and can guess where you want to add the fields
  • 93. $ ruby script/generate migration add_activation_fields_to_users perishable_token:string active:boolean Migrating in Activation Fields Rails migrations are pretty smart and can guess where you want to add the fields
  • 94. $ ruby script/generate migration add_activation_fields_to_users perishable_token:string active:boolean class AddActivationFieldsToUsers < ActiveRecord::Migration def self.up add_column :users, :perishable_token, :string add_column :users, :active, :boolean, :default => false, :null => false end def self.down remove_column :users, :active remove_column :users, :perishable_token end end Migrating in Activation Fields Rails migrations are pretty smart and can guess where you want to add the fields
  • 95. $ ruby script/generate migration add_activation_fields_to_users perishable_token:string active:boolean class AddActivationFieldsToUsers < ActiveRecord::Migration def self.up add_column :users, :perishable_token, :string add_column :users, :active, :boolean, :default => false, :null => false end def self.down remove_column :users, :active remove_column :users, :perishable_token end end Migrating in Activation Fields Rails migrations are pretty smart and can guess where you want to add the fields
  • 96. $ ruby script/generate migration add_activation_fields_to_users perishable_token:string active:boolean class AddActivationFieldsToUsers < ActiveRecord::Migration def self.up add_column :users, :perishable_token, :string add_column :users, :active, :boolean, :default => false, :null => false end def self.down remove_column :users, :active remove_column :users, :perishable_token end end $ rake db:migrate Migrating in Activation Fields Rails migrations are pretty smart and can guess where you want to add the fields
  • 97. Adding Activations We look the user up by token, activate them, and log them in
  • 98. $ ruby script/generate controller activations Adding Activations We look the user up by token, activate them, and log them in
  • 99. $ ruby script/generate controller activations class ActivationsController < ApplicationController def create if @user = User.find_using_perishable_token(params[:token]) @user.active = true # activate the user @user.save UserSession.create(@user) # log them in flash[:notice] = "User activated." else flash[:error] = "User not found." end redirect_to root_path end end Adding Activations We look the user up by token, activate them, and log them in
  • 100. $ ruby script/generate controller activations class ActivationsController < ApplicationController def create if @user = User.find_using_perishable_token(params[:token]) @user.active = true # activate the user @user.save UserSession.create(@user) # log them in flash[:notice] = "User activated." else flash[:error] = "User not found." end redirect_to root_path end end Adding Activations We look the user up by token, activate them, and log them in
  • 101. $ ruby script/generate controller activations class ActivationsController < ApplicationController def create if @user = User.find_using_perishable_token(params[:token]) @user.active = true # activate the user @user.save UserSession.create(@user) # log them in flash[:notice] = "User activated." else flash[:error] = "User not found." end redirect_to root_path end end Adding Activations We look the user up by token, activate them, and log them in
  • 102. $ ruby script/generate controller activations class ActivationsController < ApplicationController def create if @user = User.find_using_perishable_token(params[:token]) @user.active = true # activate the user @user.save UserSession.create(@user) # log them in flash[:notice] = "User activated." else flash[:error] = "User not found." end redirect_to root_path end end Adding Activations We look the user up by token, activate them, and log them in
  • 103. Email Routing We can’t make an email link POST, so I created a custom route for the action
  • 104. ActionController::Routing::Routes.draw do |map| map.resources :users map.resource :user_session map.login "login", :controller => "user_sessions", :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create" map.root :controller => "home" map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end Email Routing We can’t make an email link POST, so I created a custom route for the action
  • 105. ActionController::Routing::Routes.draw do |map| map.resources :users map.resource :user_session map.login "login", :controller => "user_sessions", :action => "new" map.logout "logout", :controller => "user_sessions", :action => "destroy" map.activate "activate/:token", :controller => "activations", :action => "create" map.root :controller => "home" map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end Email Routing We can’t make an email link POST, so I created a custom route for the action
  • 106. The Old Sign-up Our old controller logs them in as they are created and we can’t have that
  • 107. class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(params[:user]) if @user.save flash[:notice] = "Welcome!" redirect_to root_path else flash.now[:error] = "Sign-up could not be completed." render :action => :new end end end The Old Sign-up Our old controller logs them in as they are created and we can’t have that
  • 108. class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(params[:user]) if @user.save flash[:notice] = "Welcome!" redirect_to root_path else flash.now[:error] = "Sign-up could not be completed." render :action => :new end end end The Old Sign-up Our old controller logs them in as they are created and we can’t have that
  • 109. class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(params[:user]) if @user.save flash[:notice] = "Welcome!" redirect_to root_path else flash.now[:error] = "Sign-up could not be completed." render :action => :new end end end The Old Sign-up Our old controller logs them in as they are created and we can’t have that
  • 110. Creation Without Login Now we don’t log them in and we tell them to check their email
  • 111. class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(params[:user]) if @user.save_without_session_maintenance flash[:notice] = "Please check your email to activate your account." redirect_to login_path else flash.now[:error] = "Sign-up could not be completed." render :action => :new end end end Creation Without Login Now we don’t log them in and we tell them to check their email
  • 112. class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(params[:user]) if @user.save_without_session_maintenance flash[:notice] = "Please check your email to activate your account." redirect_to login_path else flash.now[:error] = "Sign-up could not be completed." render :action => :new end end end Creation Without Login Now we don’t log them in and we tell them to check their email
  • 113. class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(params[:user]) if @user.save_without_session_maintenance flash[:notice] = "Please check your email to activate your account." redirect_to login_path else flash.now[:error] = "Sign-up could not be completed." render :action => :new end end end Creation Without Login Now we don’t log them in and we tell them to check their email
  • 114. Activations in Action Let’s see what we have created
  • 115. Signing Up I can create a new user with my email address and desired password
  • 116. Signing Up I can create a new user with my email address and desired password
  • 117. Time to Check Email I wasn’t logged in, as planned
  • 118. Time to Check Email I wasn’t logged in, as planned
  • 119. Can’t Login Yet I can’t login yet either, since my account isn’t active yet
  • 120. Can’t Login Yet I can’t login yet either, since my account isn’t active yet
  • 121. log/development.rb In development mode, emails are printed to the log file (clear logs with: rake log:clear)
  • 122. Sent mail to james@graysoftinc.com Date: Sun, 7 Mar 2010 15:10:11 -0600 From: admin@secureapp.com To: james@graysoftinc.com Subject: Activate Your Account Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Welcome to the Secure Application. Please click the following link to activate your account: http://localhost:3000/activate/5HkeFFwiInKfjA4x25q9 log/development.rb In development mode, emails are printed to the log file (clear logs with: rake log:clear)
  • 123. Activated and Logged In Visiting the URL completes the process
  • 124. Activated and Logged In Visiting the URL completes the process
  • 126. User Emails Lab Your book has instructions for how to add email notifications to your application

Hinweis der Redaktion