铁轨和设计:两步确认路由错误
我正在尝试使用 Devise 像 heroku 一样进行两步确认。
我的路线:
devise_for :user, :controllers => {:confirmations => "confirmations", :registrations => "registrations" }
put "confirm_account", :to => "confirmations#confirm_account"
这是我的备用确认控制器:
class ConfirmationsController < Devise::ConfirmationsController
def show
@account = User.find_by_confirmation_token(params[:confirmation_token])
if [email protected]?
render_with_scope :new
end
end
def confirm_account
@account = User.find(params[:account][:confirmation_token])
if @account.update_attributes(params[:account]) and @account.password_match?
@account = User.confirm_by_token(@account.confirmation_token)
set_flash_message :notice, :confirmed
sign_in_and_redirect("user", @account)
else
render :action => "show"
end
end
end
这是我的 show.html.erb
:
<%= form_for(resource, :as => resource_name, :url => confirm_account_path(resource_name)) do |f| %>
<%= f.label :email %>
<%= @account.email %>
<%= f.hidden_field :confirmation_token %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.submit 'Confirm Account' %>
<%= link_to 'Home', root_url %>
<%= render :partial => 'devise/shared/links' %>
<% end %>
当我在填写密码后单击confirm
时(在单击确认电子邮件中的确认之后)。我被路由到 /confirm_account.user
这很奇怪,对吧?到底是什么原因导致这个问题呢?
编辑
rake 路线
返回:
new_user_session GET /user/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
user_session POST /user/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_user_session GET /user/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
user_password POST /user/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_user_password GET /user/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_user_password GET /user/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /user/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
cancel_user_registration GET /user/cancel(.:format) {:action=>"cancel", :controller=>"registrations"}
user_registration POST /user(.:format) {:action=>"create", :controller=>"registrations"}
new_user_registration GET /user/sign_up(.:format) {:action=>"new", :controller=>"registrations"}
edit_user_registration GET /user/edit(.:format) {:action=>"edit", :controller=>"registrations"}
PUT /user(.:format) {:action=>"update", :controller=>"registrations"}
DELETE /user(.:format) {:action=>"destroy", :controller=>"registrations"}
user_confirmation POST /user/confirmation(.:format) {:action=>"create", :controller=>"confirmations"}
new_user_confirmation GET /user/confirmation/new(.:format) {:action=>"new", :controller=>"confirmations"}
GET /user/confirmation(.:format) {:action=>"show", :controller=>"confirmations"}
user_unlock POST /user/unlock(.:format) {:action=>"create", :controller=>"devise/unlocks"}
new_user_unlock GET /user/unlock/new(.:format) {:action=>"new", :controller=>"devise/unlocks"}
GET /user/unlock(.:format) {:action=>"show", :controller=>"devise/unlocks"}
confirm_account PUT /confirm_account(.:format) {:action=>"confirm_account", :controller=>"confirmations"}
editreject_admin GET /admin/:id/editreject(.:format) {:action=>"editreject", :controller=>"admin"}
reject_admin GET /admin/:id/reject(.:format) {:action=>"reject", :controller=>"admin"}
accept_admin GET /admin/:id/accept(.:format) {:action=>"accept", :controller=>"admin"}
entries_admin_index GET /admin/entries(.:format) {:action=>"entries", :controller=>"admin"}
preferences_admin_index GET /admin/preferences(.:format) {:action=>"preferences", :controller=>"admin"}
admin_index GET /admin(.:format) {:action=>"index", :controller=>"admin"}
about_entries GET /entries/about(.:format) {:action=>"about", :controller=>"entries"}
all_entries GET /entries/all(.:format) {:action=>"all", :controller=>"entries"}
myentries_entries GET /entries/myentries(.:format) {:action=>"myentries", :controller=>"entries"}
rate_entry GET /entries/:id/rate(.:format) {:action=>"rate", :controller=>"entries"}
submit_entry PUT /entries/:id/submit(.:format) {:action=>"submit", :controller=>"entries"}
entry_comments POST /entries/:entry_id/comments(.:format) {:action=>"create", :controller=>"comments"}
entry_comment DELETE /entries/:entry_id/comments/:id(.:format) {:action=>"destroy", :controller=>"comments"}
entries GET /entries(.:format) {:action=>"index", :controller=>"entries"}
POST /entries(.:format) {:action=>"create", :controller=>"entries"}
new_entry GET /entries/new(.:format) {:action=>"new", :controller=>"entries"}
edit_entry GET /entries/:id/edit(.:format) {:action=>"edit", :controller=>"entries"}
entry GET /entries/:id(.:format) {:action=>"show", :controller=>"entries"}
PUT /entries/:id(.:format) {:action=>"update", :controller=>"entries"}
DELETE /entries/:id(.:format) {:action=>"destroy", :controller=>"entries"}
/auth/:service/callback(.:format) {:controller=>"services", :action=>"create"}
services GET /services(.:format) {:action=>"index", :controller=>"services"}
POST /services(.:format) {:action=>"create", :controller=>"services"}
root /(.:format) {:controller=>"entries", :action=>"index"}
offline /offline(.:format) {:controller=>"application", :action=>"offline"}
编辑 3 在改变中
devise_for :user, :controllers => {:confirmations => "confirmations", :registrations => "registrations" } do
match "/confirm_account", :to => "confirmations#confirm_account"
end
我收到:
当你没有的时候你有一个nil对象 期待吧!您可能期望 数组的实例。发生错误 评估 nil 时。[]
{"utf8"=>"✓",
"authenticity_token"=>"dsG/e8Tw2Oi6zEDb07R/L0yDOKFEFlse+IgLbfz3Lo0=",
"user"=>{"confirmation_token"=>"",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"},
"commit"=>"Confirm Account"}
url 中肯定有一个标记,不过……这实际上是在某个地方!
I'm trying to make a two-step confirmation like heroku using Devise.
My routes:
devise_for :user, :controllers => {:confirmations => "confirmations", :registrations => "registrations" }
put "confirm_account", :to => "confirmations#confirm_account"
Here's my alternate confirmation controller:
class ConfirmationsController < Devise::ConfirmationsController
def show
@account = User.find_by_confirmation_token(params[:confirmation_token])
if [email protected]?
render_with_scope :new
end
end
def confirm_account
@account = User.find(params[:account][:confirmation_token])
if @account.update_attributes(params[:account]) and @account.password_match?
@account = User.confirm_by_token(@account.confirmation_token)
set_flash_message :notice, :confirmed
sign_in_and_redirect("user", @account)
else
render :action => "show"
end
end
end
Here's my show.html.erb
:
<%= form_for(resource, :as => resource_name, :url => confirm_account_path(resource_name)) do |f| %>
<%= f.label :email %>
<%= @account.email %>
<%= f.hidden_field :confirmation_token %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.submit 'Confirm Account' %>
<%= link_to 'Home', root_url %>
<%= render :partial => 'devise/shared/links' %>
<% end %>
When I click confirm
after filling out the password (after clicking confirm in the confirmation email). I'm routed to /confirm_account.user
That's pretty weird, right? What's going on to cause this problem?
Edit
rake routes
returns:
new_user_session GET /user/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
user_session POST /user/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_user_session GET /user/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
user_password POST /user/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_user_password GET /user/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_user_password GET /user/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /user/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
cancel_user_registration GET /user/cancel(.:format) {:action=>"cancel", :controller=>"registrations"}
user_registration POST /user(.:format) {:action=>"create", :controller=>"registrations"}
new_user_registration GET /user/sign_up(.:format) {:action=>"new", :controller=>"registrations"}
edit_user_registration GET /user/edit(.:format) {:action=>"edit", :controller=>"registrations"}
PUT /user(.:format) {:action=>"update", :controller=>"registrations"}
DELETE /user(.:format) {:action=>"destroy", :controller=>"registrations"}
user_confirmation POST /user/confirmation(.:format) {:action=>"create", :controller=>"confirmations"}
new_user_confirmation GET /user/confirmation/new(.:format) {:action=>"new", :controller=>"confirmations"}
GET /user/confirmation(.:format) {:action=>"show", :controller=>"confirmations"}
user_unlock POST /user/unlock(.:format) {:action=>"create", :controller=>"devise/unlocks"}
new_user_unlock GET /user/unlock/new(.:format) {:action=>"new", :controller=>"devise/unlocks"}
GET /user/unlock(.:format) {:action=>"show", :controller=>"devise/unlocks"}
confirm_account PUT /confirm_account(.:format) {:action=>"confirm_account", :controller=>"confirmations"}
editreject_admin GET /admin/:id/editreject(.:format) {:action=>"editreject", :controller=>"admin"}
reject_admin GET /admin/:id/reject(.:format) {:action=>"reject", :controller=>"admin"}
accept_admin GET /admin/:id/accept(.:format) {:action=>"accept", :controller=>"admin"}
entries_admin_index GET /admin/entries(.:format) {:action=>"entries", :controller=>"admin"}
preferences_admin_index GET /admin/preferences(.:format) {:action=>"preferences", :controller=>"admin"}
admin_index GET /admin(.:format) {:action=>"index", :controller=>"admin"}
about_entries GET /entries/about(.:format) {:action=>"about", :controller=>"entries"}
all_entries GET /entries/all(.:format) {:action=>"all", :controller=>"entries"}
myentries_entries GET /entries/myentries(.:format) {:action=>"myentries", :controller=>"entries"}
rate_entry GET /entries/:id/rate(.:format) {:action=>"rate", :controller=>"entries"}
submit_entry PUT /entries/:id/submit(.:format) {:action=>"submit", :controller=>"entries"}
entry_comments POST /entries/:entry_id/comments(.:format) {:action=>"create", :controller=>"comments"}
entry_comment DELETE /entries/:entry_id/comments/:id(.:format) {:action=>"destroy", :controller=>"comments"}
entries GET /entries(.:format) {:action=>"index", :controller=>"entries"}
POST /entries(.:format) {:action=>"create", :controller=>"entries"}
new_entry GET /entries/new(.:format) {:action=>"new", :controller=>"entries"}
edit_entry GET /entries/:id/edit(.:format) {:action=>"edit", :controller=>"entries"}
entry GET /entries/:id(.:format) {:action=>"show", :controller=>"entries"}
PUT /entries/:id(.:format) {:action=>"update", :controller=>"entries"}
DELETE /entries/:id(.:format) {:action=>"destroy", :controller=>"entries"}
/auth/:service/callback(.:format) {:controller=>"services", :action=>"create"}
services GET /services(.:format) {:action=>"index", :controller=>"services"}
POST /services(.:format) {:action=>"create", :controller=>"services"}
root /(.:format) {:controller=>"entries", :action=>"index"}
offline /offline(.:format) {:controller=>"application", :action=>"offline"}
Edit 3
In changing
devise_for :user, :controllers => {:confirmations => "confirmations", :registrations => "registrations" } do
match "/confirm_account", :to => "confirmations#confirm_account"
end
I'm receiving :
You have a nil object when you didn't
expect it! You might have expected an
instance of Array. The error occurred
while evaluating nil.[]
{"utf8"=>"✓",
"authenticity_token"=>"dsG/e8Tw2Oi6zEDb07R/L0yDOKFEFlse+IgLbfz3Lo0=",
"user"=>{"confirmation_token"=>"",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"},
"commit"=>"Confirm Account"}
There's definitely a token in the url, though...This is actually going somewhere, though!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在我看来
confirm_account_path
不存在?如果您没有手动设置路由,则可以继续在
config/routes.rb
文件中将其设置为confirmations#confirm_account
。或者,如果您将 Devise 设置为使用
ConfirmationsController
,则使用new_user_confirmation_path
也可能有效(也可能无效)。在控制台中输入 rake paths 即可查看可用的路由。它们应该导致ConfirmationsController
和confirm_account
操作。编辑:尝试按如下方式编辑您的路线文件。
我认为斜杠在
confirm_account
之前很重要,因为它现在位于devise_for
块内(与devise_scope
相同) )。否则,它可能会转到users/confirm_account
。EDIT2:在控制器中使用
params[:user][:confirmation_token]
,而不是params[:account][:confirmation_token]
。但目前看来确认令牌为空。It looks to me like
confirm_account_path
doesn't exist?If you didn't set up your routes manually, you can go ahead and set that in the
config/routes.rb
file, toconfirmations#confirm_account
.Or, if you set Devise to use your
ConfirmationsController
, usingnew_user_confirmation_path
may work too (and may not). Typerake routes
in the console to see available routes. They should lead to theConfirmationsController
and theconfirm_account
action.EDIT: Try editing your routes file as follows.
I think the slash is important before
confirm_account
because it is now inside thedevise_for
block (which is identical todevise_scope
). Otherwise it may go tousers/confirm_account
.EDIT2: Use
params[:user][:confirmation_token]
, notparams[:account][:confirmation_token]
in the controller. But currently it looks like the confirmation token is blank.