Ruby实例变量在方法中不可用

时间:2013-09-19 16:35:55

标签: ruby-on-rails ruby ruby-on-rails-4 actionmailer instance-variables

我无法弄清楚为什么无法从各个邮件程序方法中访问实例变量@delivery_options ...

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 个答案:

答案 0 :(得分:3)

如果这些是“静态”数据,您可以这样做:

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

这应该有用。

如果要使用实例变量,则应执行以下操作:

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

这样,变量是在您正在使用的UserMailer实例上定义的。 你这样做的方法是在UserMail类上定义一个实例变量。

答案 1 :(得分:2)

第一个实例变量定义(@delivery_options)仅适用于类,而不适用于其方法。这就是你遇到这个问题的原因。类变量(@@delivery_options)可用于类中的所有方法,但不常用,因为类变量本身并不是线程安全的。

所有这些都说,你可能想用一个常量来定义这些并只引用常量。或者,更好的是,使用ActionMailer's default system设置一些默认传递选项,如下所示:

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

  ...
end

所有默认值都应用于邮件程序中的每个方法,但会被您在本地指定的任何选项覆盖。

相关问题