将实例变量从 Devise 控制器传递到自定义邮件程序?
Pass instance variable from Devise controller to custom mailer?
我在 Rails 应用程序中使用 Devise 进行身份验证。
在我的 registrations_controller
中,我设置了一个这样的实例变量:
class RegistrationsController < Devise::RegistrationsController
def create
@foo = "bar"
super
end
end
然后在我的自定义邮件程序中,我尝试访问 @foo
实例变量,但它只是 returns 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 instance variable to devise custom mailer in Rails?。但是 none 似乎可以解决这个问题。
首先让我解释一下你有实例变量在 ruby classes.
中工作
在ruby中,class(在你的情况下RegistrationsController
)中的实例变量(在你的情况下@foo
)不要传递给其他classes(在你的情况下 CustomMailer
) 即使继承是开的。例如考虑:
class Abc
@first = "First"
puts "Abc: #{@first}"
end
class Def < Abc
puts "Def: #{@first}"
end
# => Abc: First instance variable
# => Def:
如您所见,class Def
无法访问 @first
实例变量。因此,实例变量不会自动传递给其他 classes。
如果你想让这些变量传递给class,你应该考虑使用Class以@@
开头的实例变量。例如:
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
将自动继承 class。
现在,将上述情景与您的问题联系起来。所以你在 RegistrationsController
中创建了一个实例变量 @foo
并且它不会被传递给其他继承的 classes。 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
我在 Rails 应用程序中使用 Devise 进行身份验证。
在我的 registrations_controller
中,我设置了一个这样的实例变量:
class RegistrationsController < Devise::RegistrationsController
def create
@foo = "bar"
super
end
end
然后在我的自定义邮件程序中,我尝试访问 @foo
实例变量,但它只是 returns 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?,
首先让我解释一下你有实例变量在 ruby classes.
中工作在ruby中,class(在你的情况下RegistrationsController
)中的实例变量(在你的情况下@foo
)不要传递给其他classes(在你的情况下 CustomMailer
) 即使继承是开的。例如考虑:
class Abc
@first = "First"
puts "Abc: #{@first}"
end
class Def < Abc
puts "Def: #{@first}"
end
# => Abc: First instance variable
# => Def:
如您所见,class Def
无法访问 @first
实例变量。因此,实例变量不会自动传递给其他 classes。
如果你想让这些变量传递给class,你应该考虑使用Class以@@
开头的实例变量。例如:
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
将自动继承 class。
现在,将上述情景与您的问题联系起来。所以你在 RegistrationsController
中创建了一个实例变量 @foo
并且它不会被传递给其他继承的 classes。 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