Mel
Mel

Reputation: 2685

Rails Observers & Mailer

I am trying to figure out how to send new users a welcome email.

I asked this question yesterday https://stackoverflow.com/questions/31934734/rails-mailer-no-method-error?noredirect=1#comment51781688_31934734 It voted down (I don't know how to find out why) and was not able to get any constructive help.

I've since found rails-observer gem and am trying another approach.

My problem is that when I push this and try it out, I get an error that says: NameError (uninitialized constant UserObserver::Mailer).

My understanding of that error is that that there isn't a model that matches the name of the observer. I definitely have a user.rb model and I also have a file in my app called Mailer.

I have the following set up:

In my model folder, I have user_observer.rb:

class UserObserver < ActiveRecord::Observer
  def after_save(user)
      Mailer.welcome_mail(user).deliver!
  end
end

User/Registration_controller:

   def create
        @user = User.new(user_params) 

        respond_to do |format|
          if resource.save

            format.html { redirect_to(profiles_path)}
          else
            format.html { render action: 'new' }
            format.json { render json: @user.errors, status: :unprocessable_entity }
          end
        end
      end

app/mailers/welcome_mail.rb:

class WelcomeMail < ActionMailer::Base
  self.delivery_method = :smtp
  self.smtp_settings = {
    user_name:            ENV['WELCOME'],
    password:             ENV['D_WELCOME'],
    port:                 ...,
    domain:               'gmail.com',
    address:              'smtp.gmail.com',
    authentication:       'plain',
    enable_starttls_auto: true
  }


def new_user_waiting_for_access(user)
  @user = user
  mail(to: user.email, from: "[email protected]", subject: "Welcome #{user.first_name}")
end
end

User.rb:

  def send_user_welcome_mail
    AdminMailer.new_user_waiting_for_access(self).deliver
  end

application.rb:

config.active_record.observers = :user_observer

The specific error is:

NameError (uninitialized constant UserObserver::Mailer):
2015-08-12T03:14:33.002104+00:00 app[web.1]:   app/models/user_observer.rb:3:in `after_save'
2015-08-12T03:14:33.002106+00:00 app[web.1]:   app/controllers/users/registrations_controller.rb:21:in `block in create'
2015-08-12T03:14:33.002108+00:00 app[web.1]:   app/controllers/users/registrations_controller.rb:20:in `create'
2015-08-12T03:14:33.002109+00:00 app[web.1]: 
2015-08-12T03:14:33.002110+00:00 app[web.1]: 
2015-08-12T03:14:33.002111+00:00 app[web.1]: 
2015-08-12T03:14:33.002113+00:00 app[web.1]: NameError (uninitialized constant UserObserver::Mailer):
2015-08-12T03:14:33.002114+00:00 app[web.1]:   app/models/user_observer.rb:3:in `after_save'
2015-08-12T03:14:33.002116+00:00 app[web.1]:   app/controllers/users/registrations_controller.rb:21:in `block in create'
2015-08-12T03:14:33.002117+00:00 app[web.1]:   app/controllers/users/registrations_controller.rb:20:in `create'
2015-08-12T03:14:33.002118+00:00 app[web.1]: 

I don't understand what this error means. I have a user observer which is supposed to observe user and send a mail when the user is saved.

The content of the email is set out in a view called: welcome_mail.html.erb.

Please can anyone see what I have done wrong?

I have commented devise confirmable out - so it is not looking for confirmation. I have read others problems who may be related to devise having a view folder called mailer. I don't know what that means in the context of this problem because I'm not trying to send the mail from devise.

Upvotes: 1

Views: 544

Answers (1)

K M Rakibul Islam
K M Rakibul Islam

Reputation: 34328

In your posted code you have this: Mailer.welcome_mail(user).deliver! which is wrong because you don't have a Mailer class defined and no welcome_mail method defined as well, so this approach is wrong.

I think you want to use your defined mailer class WelcomeMail and inside WelcomeMail class you have to define a welcome_mail method where you put the logic to send the mail to the user.

Somewhat like this:

class WelcomeMail < ActionMailer::Base     
  def welcome_mail(user)
    @user = user
    @url  = 'http://example.com/login'
    mail(to: @user.email, subject: 'Welcome to My Awesome Site')
  end
end

So, your user_observer.rb becomes:

class UserObserver < ActiveRecord::Observer
  def after_save(user)
      WelcomeMail.welcome_mail(user).deliver!
  end
end

Upvotes: 2

Related Questions