我在我的Rails应用程序中使用Devise进行身份验证。
在我的registrations_controller
中,我设置了一个这样的实例变量:
class RegistrationsController < Devise::RegistrationsController
def create
@foo = "bar"
super
end
end
然后在我的自定义邮件程序中,我尝试访问@foo
实例变量,但它仅返回nil
:
class CustomMailer < Devise::Mailer
helper :application
include Devise::Controllers::UrlHelpers
def confirmation_instructions(record, token, opts={})
Rails.logger.error @foo.inspect # => nil
super
end
end
有人可以帮忙吗?
我浏览了How do I add instance variables to Devise email templates?,How to pass additional data to devise mailer?,How to pass instance variable to devise custom mailer in Rails?帖子。但是他们似乎都没有解决这个确切的问题。
答案 0 :(得分:0)
首先让我解释一下,您有实例变量在ruby类中工作。
在ruby中,即使一个类(在您的情况下@foo
)中的实例变量(在您的情况下RegistrationsController
)也不会传递给其他类(在您的情况下CustomMailer
),即使继承为ON。例如,请考虑:
class Abc
@first = "First"
puts "Abc: #{@first}"
end
class Def < Abc
puts "Def: #{@first}"
end
# => Abc: First instance variable
# => Def:
如您所见,类Def
无法访问@first
实例变量。因此,实例变量不会自动传递给其他类。
如果希望这些变量传递给类,则应考虑使用以@@
开头的类实例变量。例如:
class Abc
@@first = "First instance variable"
puts "Abc: #{@@first}"
end
class Def < Abc
puts "Def: #{@@first}"
end
# => Abc: First instance variable
# => Def: First instance variable
现在@@first
将自动传递到继承的类。
现在,将以上senario与您的问题相关。因此,您正在@foo
中创建实例变量RegistrationsController
,并且该变量不会传递给其他继承的类。 Devise::RegistrationsController
和DeviseMailer
都是从Devise.parent_controller
继承的。
因此,更好的方法是将@foo
作为参数发送,例如:
class RegistrationsController < Devise::RegistrationsController
def create
@foo = "bar"
CustomMailer.confirmation_instructions(user, token, opts={foo: @foo})
...
end
end
然后您可以在CustomMailer中访问它:
def confirmation_instructions(record, token, opts={})
puts opts[:foo]
super
end