我正在尝试覆盖Devise控制器以进行一些小的更改,例如在请求未注册的电子邮件地址的确认电子邮件时添加Flash消息。
我试图以这种方式覆盖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
的代码,该代码本身称为successfully_sent?(resource)
successfully_sent?
方法在InternalHelpers
2中定义,这就是为什么我尝试添加include Devise::Controllers::InternalHelpers
这不是我第一次尝试覆盖Devise控制器,这不是我第一次失败。我总是设法得到一个解决方法,但我想了解我所缺少的...提前感谢您的帮助!
[编辑] Devise的版本是1.4.9 Rails是3.0.10
答案 0 :(得分:2)
嗯,感谢Kyle在我的问题评论中的帮助,我会为这个初学者的错误写出正确答案。
我只是在看Devise的Github存储库,而不是查看我自己的Devise版本来覆盖控制器。由于我试图覆盖的控制器在我的版本和最后一个提交的版本之间发生了变化,我试图使用的辅助方法根本没有在我的版本中定义...
如Kyle所示,您可以使用bundle open devise
查看您实际使用的gem的代码,或者您可以使用gem list devise
查看其版本号并找到此代码在Github上发布(对于Devise,他们为每个版本设置了标签,以便您可以通过选择相应的标签来浏览版本1.4.9的代码。)
这样做,我会用以下代码覆盖我的控制器的create
方法:
def create
self.resource = resource_class.send_confirmation_instructions(params[resource_name])
if successful_and_sane?(resource)
set_flash_message(:notice, :send_instructions) if is_navigational_format?
respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
else
respond_with_navigational(resource){ render_with_scope :new }
end
end
使用successful_and_sane?
而非successfully_sent?
...
总结这个答案,可能有一种更好的方法是将Flash消息添加到此方法而不是覆盖它。 jarrad建议使用around_filter
,但是我无法让它工作,我不确定在我从过滤方法中得出它之后我仍然可以改变渲染视图......欢迎评论!
答案 1 :(得分:1)
这可能无法帮助您理解为什么覆盖Devise控制器失败,但它会使您的代码保持干净,因为您不需要从Devise::ConfirmationsController#crete
复制代码
因此,如果您只想设置Flash消息,请查看Filters for ActionControllers
具体来说,看看周围过滤器:
class ConfirmationsController < Devise::ConfirmationsController
around_filter :my_custom_stuff, :only => :create
private
def my_custom_stuff
# do your thing here...
end
end