覆盖 Devise 控制器的问题
我正在尝试覆盖 Devise 控制器以进行一些细微的更改,例如在请求未注册电子邮件地址的确认电子邮件时添加一条闪存消息。
我尝试覆盖 Devise::ConfirmationsController
1这样:
# app/controllers/confirmations_controller.rb
class ConfirmationsController < Devise::ConfirmationsController
include Devise::Controllers::InternalHelpers # tried to add this, no success
def create
self.resource = resource_class.send_confirmation_instructions(params[resource_name])
if successfully_sent?(resource)
respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
else
respond_with(resource)
end
end
end
我想我添加了路线正确:
devise_for :users, :controllers => { :confirmations => "confirmations" }
我的控制器方法被调用,但是它引发了此异常:
NoMethodError in ConfirmationsController#create
undefined method `successfully_sent?' for #<ConfirmationsController:0x007fa49e229030>
在我重写的控制器中,我刚刚复制了 Devise::ConfirmationsController#create
的代码,它本身调用 successively_sent?(resource)
successively_sent?
方法在 InternalHelpers
中定义 2,这就是我尝试添加 include Devise::Controllers::InternalHelpers
这不是我第一次尝试覆盖 Devise 控制器,这不是我第一次失败。我总是设法找到解决方法,但我想了解我缺少什么......提前感谢您的帮助!
[编辑] Devise 版本为 1.4.9 Rails 是 3.0.10
I'm trying to override a Devise controller to have some minor changes, for example adding a flash message when requesting a confirmation email for an unregistered email address.
I tried to override Devise::ConfirmationsController
1 this way:
# app/controllers/confirmations_controller.rb
class ConfirmationsController < Devise::ConfirmationsController
include Devise::Controllers::InternalHelpers # tried to add this, no success
def create
self.resource = resource_class.send_confirmation_instructions(params[resource_name])
if successfully_sent?(resource)
respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
else
respond_with(resource)
end
end
end
I think I added the route correctly:
devise_for :users, :controllers => { :confirmations => "confirmations" }
My controller method gets called, however it raises this exception:
NoMethodError in ConfirmationsController#create
undefined method `successfully_sent?' for #<ConfirmationsController:0x007fa49e229030>
In my overridden controller, I just copied the code of Devise:: ConfirmationsController#create
, which itself calls successfully_sent?(resource)
The successfully_sent?
method is defined in InternalHelpers
2, this is why I tried to add include Devise::Controllers::InternalHelpers
This is not the first time I try to override a Devise controller, and this is not the first time I fail. I always managed to get a workaround, but I'd like to understand what I'm missing... Thanks in advance for your help!
[EDIT]
Devise is in version 1.4.9
Rails is 3.0.10
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,感谢凯尔在我的问题评论中的帮助,我将为这个初学者的错误写出正确的答案。
我没有查看我自己的 Devise 版本来覆盖控制器,而是只是查看 Devise 的 Github 存储库。由于我尝试覆盖的控制器在我的版本和最后提交的版本之间发生了更改,因此我尝试使用的帮助器方法根本没有在我的版本中定义...
正如凯尔所指出的,您可以使用 < code>bundle open devise 查看您实际使用的 gem 的代码,或者您可以使用
gem list devise
查看其版本号,并在Github(对于 Devise,他们为每个版本设置了标签这样您就可以通过选择相应的标签来浏览1.4.9版本的代码)。这样做,我会使用以下代码覆盖控制器的
create
方法:使用
successful_and_sane?
而不是successively_sent?
...它 总结这个答案,可能有一种更好的方法来向此方法添加闪现消息,而不是覆盖它。 jarrad 建议使用
around_filter
,但我还无法让它工作,而且我不确定在从过滤器方法中生成渲染视图后是否仍然可以更改渲染视图...欢迎评论!Well, thanks to the help of Kyle in my question's comments, I will write the correct answer to this beginner's mistake.
Instead of looking at my own version of Devise to override the controller, I was simply looking at Devise's Github repository. Since the controller I was trying to override had changes between my version and the last committed one, the helper method I was trying to use was simply not defined in my version...
As indicated by Kyle, you can use
bundle open devise
to look at the code of the gem you're actually using, or you can look at its version number withgem list devise
and find the code for this release on Github (for Devise they set the tags for each release so that you can browse the code for release 1.4.9 by selecting the corresponding tag).Doing this, I would have overrode my controller's
create
method with the following code instead:which uses
successful_and_sane?
and notsuccessfully_sent?
...To conclude this answer, there may be a better way of adding a flash message to this method than overriding it. jarrad is advising to use
around_filter
, but I can't get it to work yet and I'm unsure I can still change the rendered view after I yielded it from the filter method... Comments welcomed!这可能无法帮助您理解为什么重写 Devise 控制器失败,但它会使您的代码保持干燥,因为您不需要从
Devise::ConfirmationsController#crete
复制代码所以,如果您只是想要设置 Flash 消息,请查看 过滤器ActionControllers
具体来说,看看周围过滤器:
This may not help you understand why overriding the Devise controller is failing, but it will keep your code DRY in that you do not need to copy the code from
Devise::ConfirmationsController#crete
So, if you just want to set a flash message, look at Filters for ActionControllers
Specifically, look at the Around Filter: