Проблема с Rails 3 Routes

#ruby-on-rails #routes #authlogic

#ruby-on-rails #маршруты #authlogic

Вопрос:

Я начинающий разработчик, и я смог успешно использовать этот учебник (я в Rails 3): http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic / чтобы разрешить пользователям сбрасывать свои пароли, однако у меня также есть модель клиента, для которой мне нужно это сделать, и я сталкиваюсь с проблемами (перечисленными ниже кода). Я думаю, что ошибка в моей маршрутизации, но я не уверен, как это исправить.

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
  

МОДЕЛИРУЕТ модель user.rb

 def deliver_password_reset_instructions!
reset_perishable_token!
UserMailer.password_reset_instructions(self).deliver
end
  

модель customer.rb

 def deliver_customer_password_reset_instructions!
 reset_perishable_token!
 UserMailer.customer_password_reset_instructions(self).deliver
end
  

ПРОСМОТРЫ
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/редактировать

 <% 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 %>
  

Он отлично работает для кода, к которому не добавлено «customer». Генерируется токен, и я могу отправить электронное письмо с тем же форматом для URL: /password_resets//edit_customer

Однако при попытке получить URL-адрес выдается сообщение об ошибке. С помощью приведенного выше кода я получаю эту ошибку: «Маршрут не соответствует {:action=>»show», :controller=>»password_resets»}» — я также вижу, что он интерпретирует :id как идентификатор контроллера (который отличается от того, как работает пользовательский- он правильно интерпретирует идентификатор как токен.

Я много экспериментировал:

  • изменить: идентификатор в контроллере для edit_customer в load_customer_using_perishable_token на perishable_token, customer.perishable_token, @customer.perishable_token)
  • попытался добавить их в «get ‘edit_customer'», используя помощник пути (=> «cust_pass») — :path, : path_name, :as, чтобы я мог изменить URL на cust_pass_path
  • я даже пытался добавить это в маршруты, просто чтобы посмотреть, будет ли это работать в соответствии с ‘/ password_resets/:id / edit_customer’ => ‘password_resets#edit_customer’

Итак, я в тупике. Любая помощь будет с благодарностью!

Комментарии:

1. Не используйте одно действие как для post, так и для get.

Ответ №1:

Хорошо, по моей интерпретации, вы получаете электронное письмо, но нажатие на ссылку выдает ошибку? Для начала с сообщения об ошибке

 "No route matches {:action=>"show", :controller=>"password_resets"}"
  

появляется, потому что вы пытаетесь вызвать действие show в вашем контроллере password_resets, но оно не определено. Первое, что вы должны сделать, это исключить его из своих маршрутов.

 resources :password_resets, :except => :destroy do
  get 'edit_customer'
  post 'edit_customer'
end
  

Я не думаю, что это решит вашу проблему, но наличие маршрутов, которые никуда не ведут, бессмысленно. Во-вторых, убедитесь, что у вас нет ничего, что связано с действием show. Поскольку ошибка, похоже, возникает при нажатии на ссылку в электронном письме, я бы подумал, что отправляемая вами ссылка неверна.

Комментарии:

1. Также я думаю, вам нужно определить свои маршруты для edit_customer и update_customer и обновить свою форму edit_customer, чтобы отразить это.

2. И оператор if сразу после elseif в вашем действии create является избыточным. Вы могли бы просто сделать elseif @customer

Ответ №2:

Я смог исправить это, обновив URL-адрес в edit_customer.rb

От

 :url => password_reset_path
  

Для

 :url => {:action=>"update_customer", :controller=>"password_resets"}
  

Мне также пришлось обновить свой route.rb

От

 resources :password_resets do
 get 'edit_customer'
 post 'edit_customer'
end
  

Для

 resources :password_resets, :except => [:index, :destroy, :show] do
  get 'edit_customer'
  put 'update_customer'
end