我正在尝试使用Rails邮件程序,但是当我尝试注册新用户并发送激活电子邮件时,我收到以下错误消息。我正在关注Hartl最新的(第3版)轨道教程的第10章,所以理论上它应该有效:
No route matches {:action=>"edit", :controller=>"account_activations", :email=>"joe@bloggmail.com", :format=>nil, :id=>nil} missing required keys: [:id]
app/views/user_mailer/account_activation.html.erb:9:in `_app_views_user_mailer_account_activation_html_erb__1296124105699284853_2236858900'
app/mailers/user_mailer.rb:6:in `account_activation'
app/models/user.rb:82:in `send_activation_email'
app/controllers/users_controller.rb:27:in `create'
相关的代码位是:
用户模型:
class User < ActiveRecord::Base
attr_accessor :remember_token, :activation_token
extend FriendlyId
friendly_id :callsign, :use => :slugged
has_secure_password
before_save do
self.email.downcase!
self.callsign.downcase!
end
before_create do
:create_activation_digest
end
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
VALID_CALLSIGN_REGEX = /\A[a-z\d\-.\_]+\z/i
validates :callsign, presence: true,
length: { maximum: 20 },
format: { with: VALID_CALLSIGN_REGEX },
uniqueness: { case_sensitive: false }
validates :password, length: { minimum: 6 }
validates :slug, presence: true
# Returns the hash digest of the given string.
def self.digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
# Returns a random token.
def self.new_token
SecureRandom.urlsafe_base64
end
# Remembers a user in the database for use in persistent sessions.
def remember
self.remember_token = User.new_token
update_attribute(:remember_digest, User.digest(remember_token))
end
# Forgets a user.
def forget
update_attribute(:remember_digest, nil)
end
# Returns true if the given token matches the digest.
def authenticated?(attribute, token)
digest = send("#{attribute}_digest")
return false if digest.nil?
BCrypt::Password.new(digest).is_password?(token)
end
# Activates an account.
def activate
update_attribute(:activated, true)
update_attribute(:activated_at, Time.zone.now)
end
# Sends activation email.
def send_activation_email
UserMailer.account_activation(self).deliver_now
end
private
# Creates and assigns the activation token and digest.
def create_activation_digest
self.activation_token = User.new_token
self.activation_digest = User.digest(activation_token)
end
end
用户控制器:
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :show, :edit, :update, :destroy]
before_action :non_logged_in_user, only: [:new, :create]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
@users = User.paginate(page: params[:page])
end
def show
@user = User.friendly.find(params[:id])
@page_name = "user_page"
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
@user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end # create
def destroy
@user = User.find(params[:id])
if ( current_user != @user )
@user.destroy
flash[:success] = "User deleted."
redirect_to users_url
else
redirect_to @user, notice: "Suicide is not permitted, admin chappie. Hard cheese."
end
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end # update
private
def user_params
params.require(:user).permit(:name, :email, :callsign, :password, :password_confirmation)
end
# Before filters
def non_logged_in_user
if logged_in?
redirect_to root_url, notice: "Nice try pal. You can't create a new user
if you're already signed in."
end
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
account_activation.html.erb:
<h1>MySite</h1>
<p>Hi <%= @user.name %>,</p>
<p>
Welcome! Click on the link below to activate your account:
</p>
<%= link_to "Activate", edit_account_activation_url(@user.activation_token,
email: @user.email) %>
user_mailer.rb:
class UserMailer < ActionMailer::Base
default from: "noreply@mysite.com"
def account_activation(user)
@user = user
mail to: user.email, subject: "Account activation"
end
def password_reset
@greeting = "Hi"
mail to: "to@example.org"
end
end
routes.rb中:
Mysite::Application.routes.draw do
resources :users
resources :account_activations, only: [:edit]
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
end
编辑: account_activations_controller.rb:
class AccountActivationsController < ApplicationController
def edit
user = User.find_by(email: params[:email])
if user && !user.activated? && user.authenticated?(:activation, params[:id])
user.activate
log_in user
flash[:success] = "Account activated!"
redirect_to user
else
flash[:danger] = "Invalid activation link"
redirect_to root_url
end
end
end
答案 0 :(得分:1)
我建议在路由文件中使用它而不是资源:
get 'account_activation', "account_activations#edit", :as => :edit_account_activation
......并在那里处理秘密令牌和电子邮件地址参数。
目前问题是您没有控制器操作来匹配您在account_activation.html.erb中使用的路线
答案 1 :(得分:0)
发现错误。 问题是User类中的这段代码:
before_create do
:create_activation_digest
end
应该是:
before_create do
create_activation_digest
end
或者:
before_create :create_activation_digest
小学生错误。我为浪费每个人的时间而道歉。
(因此代码:
resources :account_activations, only: [:edit]
routes.rb中的确实创建了正确的路由)