实现重新发送令牌功能时的URL问题

时间:2016-08-10 03:02:53

标签: ruby-on-rails ruby

在我开始解释这个问题之前,我将简要介绍一下这个功能。当用户注册时,他们会在电子邮件中获得一个激活令牌,该令牌将在2小时后到期。我试图实现一项允许用户在其电子邮件中重新发送激活令牌的功能。

重发激活令牌功能的代码如下所示。

用户控制器中的控制器代码

 def resend_verification_email
    @user = User.find_by(email: params[:resend_verification_email] [:email].downcase)
    if valid_email(params[:resend_verification_email] [:email])
      if !@user 
        redirect_to resend_verification_path
        flash[:danger] = "Email does not exist"
      elsif
        !@user.activated?
        UserMailer.resend_activation(@user).deliver_now
        flash[:success] = "Check your email for the activation token"
        redirect_to resend_verification_path
      else
        redirect_to resend_verification_path
        flash[:success] = "User is already activated."             
      end
    else
      flash[:danger] = "Email format is Invalid"
      redirect_to resend_verification_path
    end
  end

帐户激活控制器

class AccountActivationsController < ApplicationController

def edit
  user = User.find_by(email: params[:email])
  if user && !user.activated? && user.authenticated?(:activation, params[:id]) #the token is actually available by params id
    user.activate
    log_in user
    flash[:success] = "Account activated."
    redirect_to home_path
  else
    flash[:danger] = "Invalid activation link"
    redirect_to root_url
  end
end


end

邮件程序控制器方法

def resend_activation(user)
    @user = user
    @userid = user.id
    mail to: user.email, subject: "Account activation"
  end

邮件程序视图

<%= link_to "Activate your account", edit_account_activation_url(id: @user.activation_token, email: @user.email) %>

我收到以下错误。 No route matches {:action=>"edit", :controller=>"account_activations", :email=>"example@gmail.com", :id=>nil} missing required keys: [:id]

我明白错误在说什么。 url的第一个参数是令牌,抓取的方式是通过params [:id],因为在RESTful路由中,id始终是第一个参数。如果我删除了URL,电子邮件将被发送出去。 URL正在抛出该错误,我不确定为什么。任何帮助,将不胜感激。谢谢!

我只包括相关路线。

  get 'resend_verification'  => 'users#resend_verification'
  post 'resend_verification_email'  => 'users#resend_verification_email'

  resources :account_activations, only: [:edit]
  resources :password_resets,     only: [:new, :create, :edit, :update]

相关的佣金路线

edit_account_activation GET    /account_activations/:id/edit(.:format)                                          account_activations#edit

                    users GET    /users(.:format)                                                                 users#index
                          POST   /users(.:format)                                                                 users#create
                 new_user GET    /users/new(.:format)                                                             users#new
                edit_user GET    /users/:id/edit(.:format)                                                        users#edit
                     user GET    /users/:id(.:format)                                                             users#show
                          PATCH  /users/:id(.:format)                                                             users#update
                          PUT    /users/:id(.:format)                                                             users#update
                          DELETE /users/:id(.:format)                                                             users#destroy


resend_verification GET    /resend_verification(.:format)                                                   users#resend_verification
resend_verification_email POST   /resend_verification_email(.:format)                                             users#resend_verification_email

3 个答案:

答案 0 :(得分:1)

好吧,我不会将account_activations定义为一条足智多谋的路线。

评论:#the token is actually available by params id解释了原因,imo id应该引用模型资源。

以下是该问题的解决方法:

  1. 将路线定义为:
  2. get "/account_activations/edit", to: "account_activations#edit", as: 'edit_account_activation'

    1. 按如下方式定义激活链接:
    2. <%= link_to "Activate your account", edit_account_activation_url(token: @user.activation_token, email: @user.email) %>

      1. 更新控制器:
      2. class AccountActivationsController < ApplicationController def edit user = User.find_by(email: params[:email]) if user && !user.activated? && user.authenticated?(:activation, params[:token]) #... rest of code...

        或者,如果您真的想保持现状,请尝试重新定义电子邮件链接,如下所示:

        <%= link_to "Activate your account", edit_account_activation_url(@user.activation_token, email: @user.email) %>

        然后,params[:id]可能会引用您提供的令牌。

答案 1 :(得分:0)

重新定义您的电子邮件链接,如下所示:

<%= link_to "Activate your account", edit_account_activation_path( @user.activation_token, @user.email) %>

或者您只需将对象的主键传递给控制器​​即可:@user.id并使用

before_action :set_user, only: [:edit]  

在控制器内部为set user ex定义私有方法:

private 
  def set_user
    @user = User.find_by_id(params[:id])
    redirect_to xyz_path if @user.blank?
  end

答案 2 :(得分:0)

:activation_token几乎创建为attr_accessor

这不是路由问题。

@user.activation_token

实际上是返回零。

如果您希望发送更多验证电子邮件,则需要将activation_token保存到用户模型。