Rails 3 Routes Issue
I am a beginning developer, and I was able to successfully use this tutorial (I'm in Rails 3): http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic/ to allow for users to reset their passwords, however I also have a customer model that I need to do this for, and I'm running into issues (listed below code). I think the error is my routing, but I'm not sure how to fix it.
routes.rb
resources :password_resets do
get 'edit_customer'
post 'edit_customer'
end
password_resets_controller.rb
class PasswordResetsController < ApplicationController
before_filter :load_user_using_perishable_token, :only => [:edit, :update]
before_filter :load_customer_using_perishable_token, :only => [:edit_customer, :update_customer]
before_filter :require_no_user, :require_no_customer
def new
render
end
def create
@user = User.find_by_email(params[:email])
@customer = Customer.find_by_email(params[:email])
if @user
@user.deliver_password_reset_instructions!
flash[:notice] = "Instructions to reset your password have been emailed to you. " +
"Please check your email."
redirect_to new_user_session_path
elsif
if @customer
@customer.deliver_customer_password_reset_instructions!
flash[:notice] = "Instructions to reset your password have been emailed to you. " +
"Please check your email."
redirect_to new_customer_session_path
end
else
flash[:notice] = "No account was found with that email address"
render :action => :new
end
end
def edit
render
end
def edit_customer
#redirect_to edit_customer_password_resets_path
end
def update
@user.password = params[:user][:password]
@user.password_confirmation = params[:user][:password_confirmation]
if @user.save
flash[:notice] = "Password successfully updated"
redirect_to new_user_session_path
else
render :action => :edit
end
end
def update_customer
@customer.password = params[:customer][:password]
@customer.password_confirmation = params[:customer][:password_confirmation]
if @customer.save
flash[:notice] = "Password successfully updated"
redirect_to new_customer_session_path
else
render :action => :edit
end
end
private
def load_user_using_perishable_token
@user = User.find_using_perishable_token(params[:id])
unless @user
flash[:notice] = "We're sorry, but we could not locate your account." +
"If you are having issues try copying and pasting the URL " +
"from your email into your browser or restarting the " +
"reset password process."
redirect_to new_user_session_path
end
end
def load_customer_using_perishable_token
@customer = Customer.find_using_perishable_token(params[:id])
unless @customer
flash[:notice] = "We're sorry, but we could not locate your account." +
"If you are having issues try copying and pasting the URL " +
"from your email into your browser or restarting the " +
"reset password process."
#redirect_to new_customer_session_path
end
end
end
MODELS user.rb model
def deliver_password_reset_instructions!
reset_perishable_token!
UserMailer.password_reset_instructions(self).deliver
end
customer.rb model
def deliver_customer_password_reset_instructions!
reset_perishable_token!
UserMailer.customer_password_reset_instructions(self).deliver
end
VIEWS password_resets/new
<% form_tag password_resets_path do %>
<p>Email:</p>
<%= text_field_tag "email" %><br />
<br />
<%= submit_tag "Reset my password" %>
<% end %>
password_resets/edit
<% form_for @user, :url => password_reset_path, :method => :put do |f| %>
<%= f.label :password %><br />
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Change my password and log me in"%>
<% end %>
password_resets/edit_customer
<% form_for @customer, :url => password_reset_path, :method => :put do |f| %>
<%= f.label :password %><br />
<%= f.开发者_如何转开发password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Change my password and log me in" %>
<% end %>
It works perfectly for the code that does not have "customer" appended to it. The token generates, and I can get the email to send with the same format for the url: /password_resets//edit_customer
However, it receives an error when I try to pull up the url. With the code above, I receive this error: "No route matches {:action=>"show", :controller=>"password_resets"}" - I can also see that it interprets the :id to be the id of the controller (which is different than how the user one works - it correctly interprets the id as the token.
I have experimented a lot:
- change :id in controller for edit_customer in load_customer_using_perishable_token to perishable_token, customer.perishable_token, @customer.perishable_token)
- tried to append these to "get 'edit_customer'" using the path helper (=> "cust_pass") - :path, :path_name, :as so i could change the url to cust_pass_path
- i even tried to add this to the routes just to see if it would work match '/password_resets/:id/edit_customer' => 'password_resets#edit_customer'
So I stumped. Any help would be greatly appreciated!
Ok by my interpretation you are recieving the email, but clicking the link gives you an error? To start with the error message
"No route matches {:action=>"show", :controller=>"password_resets"}"
is appearing because you are trying to call the show action in your password_resets contoller, but it is not defined. First thing you should do is exclude it from your routes.
resources :password_resets, :except => :destroy do
get 'edit_customer'
post 'edit_customer'
end
I dont think it will fix your problem, but having routes that go nowhere is kind of pointless. Secondly make sure you do not have anything linking to the show action. As the error seems to be occuring when you click the link in the email I would think that the link you are sending is not correct.
I was able to fix this by updating the url in edit_customer.rb
from
:url => password_reset_path
to
:url => {:action=>"update_customer", :controller=>"password_resets"}
I also had to update my route.rb
from
resources :password_resets do
get 'edit_customer'
post 'edit_customer'
end
to
resources :password_resets, :except => [:index, :destroy, :show] do
get 'edit_customer'
put 'update_customer'
end
精彩评论