在我开始解释这个问题之前,我将简要介绍一下这个功能。当用户注册时,他们会在电子邮件中获得一个激活令牌,该令牌将在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
答案 0 :(得分:1)
好吧,我不会将account_activations
定义为一条足智多谋的路线。
评论:#the token is actually available by params id
解释了原因,imo id
应该引用模型资源。
以下是该问题的解决方法:
get "/account_activations/edit", to: "account_activations#edit", as: 'edit_account_activation'
<%= link_to "Activate your account", edit_account_activation_url(token: @user.activation_token, email: @user.email) %>
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保存到用户模型。