Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3: Send welcome e-mail using Devise

How can I send a welcome e-mail when a user registers to my service?

Also, how do I change the e-mails :from and :subject field from Devise?

Thanks

like image 320
donald Avatar asked Dec 29 '10 11:12

donald


3 Answers

I can't use the "approved" answer because I'm not using Devise's :confirmable.

I didn't like the other solutions because you have to use model callbacks, which will always send welcome emails even when you create his account in the console or an admin interface. My app involves the ability to mass-import users from a CSV file. I don't want my app sending a surprise email to all 3000 of them one by one, but I do want users who create their own account to get a welcome email. The solution:

1) Override Devise's Registrations controller:

#registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController

  def create
    super
    UserMailer.welcome(resource).deliver unless resource.invalid?
  end

end

2) Tell Devise you overrode its Registrations controller:

# routes.rb
devise_for :users, controllers: { registrations: "registrations" }

Of course, you can adapt "UserMailer" and "devise_for :users" to match the model name you're using.

like image 157
Arcolye Avatar answered Oct 14 '22 17:10

Arcolye


I did it by overriding devise's confirm! method: https://gist.github.com/982181

class User < ActiveRecord::Base
  devise :invitable, :database_authenticatable, :registerable, :recoverable, 
         :rememberable, :confirmable, :validatable, :encryptable

  # ...

  # devise confirm! method overriden
  def confirm!
    welcome_message
    super
  end

  # ...

private

  def welcome_message
    UserMailer.welcome_message(self).deliver
  end

end
like image 40
Ben Orozco Avatar answered Oct 14 '22 17:10

Ben Orozco


This is a great discussion. Overriding the method as benoror suggests will work great. If you think you might want to capture other user events, then as some others have suggested elsewhere an Observer class might be the cleanest approach. This solution is for Rails 3.0.x and 3.1.

To set up an observer, you make the following changes to your application file, adding this observer to any others you might already have.

#config/application.rb
config.active_record.observers = :user_observer

Then create a new file in the models directory:

#app/models/user_observer.rb
class UserObserver < ActiveRecord::Observer 
  def after_create(user)
    Notifier.user_new(user).deliver
  end  
end

If you have a cucumber test that exercises the create user functions, you can add this step to that feature and back it up with a worker step to check for an email in the test mail array.

#features/users/sign_up.feature for example
Scenario: User signs up with valid data
  ...
  And I should receive an email with "[Text from your welcome message]"


#features/common_steps.rb
Then /^I should receive an email with "([^"]*)"$/ do |value|
  # this will get the most recent email, so we can check the email headers and body.
  ActionMailer::Base.deliveries.should_not be_empty
  @email = ActionMailer::Base.deliveries.last
  @email.body.should include(value)
  #@email.from.should == ["[email protected]"]
end

You environments/test.rb should have these settings to build a mail array instead of sending:

config.action_mailer.delivery_method = :test
config.action_mailer.perform_deliveries = true

Needless to say you can test for much more (to, from, etc) in the message, but this will get your started in a BDD manner if you are so inclined.

See also some older StackOverflow threads with insight into this question include:

  • How can I send a welcome email to newly registered users in Rails using Devise?
  • Using Rails and Devise, I want to send a welcome email on sign up.
like image 22
Charles Forcey Avatar answered Oct 14 '22 16:10

Charles Forcey