我在 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? 。但他们似乎都没有解决这个确切的问题。
最佳答案
首先让我解释一下您可以在 ruby 类中使用实例变量。
在ruby中,类(在您的情况下RegistrationsController
)中的实例变量(在您的情况下@foo
)不会传递给其他类(在您的情况下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
将自动传递给继承类。
现在,将上述情况与您的问题联系起来。因此,您在 RegistrationsController
中创建一个实例变量 @foo
,并且它不会传递给其他继承的类。在底层,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
关于ruby-on-rails - 将实例变量从设计 Controller 传递到自定义邮件程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57501436/