1

I can't figure out why the instance variable @delivery_options isn't accessible from within the individual mailer methods...

class UserMailer < ActionMailer::Base

    @delivery_options = {
            user_name: 'foo',
            password: 'bar',
            address: 'smtp.foobar.net'
    }

    def invite_email (email, project)
        logger.debug( @delivery_options ) #WHY IS THIS IS UNDEFINED??
        @project = project

        #THIS WORKS FINE
        mail(to: email, subject: "WORK DAMMIT", delivery_method_options: {
                user_name: 'foo',
                password: 'bar',
                address: 'smtp.foobar.net'
        })

        #THIS FAILS
        #mail(to: email, subject: "WORK DAMMIT", delivery_method_options: @delivery_options)

    end


end

2 Answers 2

3

If these are "static" data, you could just do:

class UserMailer < ActionMailer::Base

    DELIVERY_OPTIONS = {
        user_name: 'foo',
        password: 'bar',
        address: 'smtp.foobar.net'
    }

    def invite_email(email, project)
        mail(to: email, subject: "WORK DAMMIT", delivery_method_options: DELIVERY_OPTIONS)
        ...
    end
end

This should work.

If you want to use an instance variable, you should do something like:

class UserMailer < ActionMailer::Base

    def initialize
        @delivery_options = {
            user_name: 'foo',
            password: 'bar',
            address: 'smtp.foobar.net'
        }
    end

    def invite_email(email, project)
        mail(to: email, subject: "WORK DAMMIT", delivery_method_options: @delivery_options)
        ...
    end
end

This way, the variable is defined on the instance of UserMailer you are using. The way you did it was defining an instance variable on the UserMail class.

Sign up to request clarification or add additional context in comments.

2 Comments

Cool. I'm a Ruby n00b but I think your code uses a constant. I'll give it a try. In the mean time, can you explain why the scope of the instance variable doesn't reach into the methods. Is that not normal Ruby practice?
Edited my answer to add some explanations.
2

The first instance variable definition (@delivery_options) is available only to the class, not its methods. That's why you're running into this problem. Class variables (@@delivery_options) are available to all methods in a class, but aren't as frequently used because class variables are not inherently thread safe.

All this said, you probably want to use a constant to define these and just reference the constant. Or, even better, set some default delivery options using ActionMailer's default system like so:

class UserMailer < ActionMailer::Base
  default {user_name: 'foo', password: 'bar', address: 'smtp.foobar.net'}

  ...
end

All defaults are applied to every method in the mailer, but overriden by any options you specify locally.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.