我跟着RailsCast 274添加了记住我&重置密码功能到我的应用程序。
我在本地没有问题,该应用似乎运行并验证用户是否正常。问题是当我将生产版本部署到Heroku时出现错误:
undefined method `find_by_auth_token!' for #<Class:0x007f35fbe37a78>
current_user
在我的ApplicationController
中定义为:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :current_user
before_action :require_user
def current_user
@current_user ||= User.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]
end
def require_user
if current_user.nil?
redirect_to new_session_path
end
end
end
这是我的SessionsController
:
class SessionsController < ApplicationController
layout false
skip_before_action :require_user
def create
user = User.find_by(email: params["email"])
if user && user.authenticate(params["password"])
if params[:remember_me]
cookies.permanent[:auth_token] = user.auth_token
else
cookies[:auth_token] = user.auth_token
end
redirect_to root_path, notice: "Login successful!"
else
redirect_to new_session_path, alert: "Email or password incorrect"
end
end
def destroy
cookies.delete(:auth_token)
redirect_to new_session_path, notice: "Logout successful!"
end
end
这是User
模型:
class User < ActiveRecord::Base
has_secure_password
has_one :patient, :dependent => :destroy
has_one :clinician, :dependent => :destroy
accepts_nested_attributes_for :patient, :allow_destroy => true
accepts_nested_attributes_for :clinician, :allow_destroy => true
validates :password,
:length => { :minimum => 6 }, :if => :password_digest_changed?
validates_presence_of :password, on: :create
before_validation(on: :update) do
# only want confirmation validation to run if user enters password
self.password_confirmation = nil unless self.password.present?
end
# validates_uniqueness_of :email
before_create { generate_token(:auth_token) }
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
end
在我的schema.rb
:
create_table "users", force: true do |t|
t.string "timezone"
t.boolean "terms_agreement", default: false
t.string "email"
t.string "password_digest"
t.string "auth_token"
t.string "password_reset_token"
t.datetime "password_reset_sent_at"
end
为什么这是在开发中而不是在生产中?
Ruby 2.2.1
&amp; Rails 4.1.8
发展:
PostgresSQL 9.4.1
答案 0 :(得分:1)
这是一个旧教程,rails 4有不同的动态匹配器
Rails 3
User.find_by_auth_token!(cookies[:auth_token])
Rails 4
User.find_by!(auth_token: cookies[:auth_token])