I followed RailsCast 274 to add Remember Me & Reset Password functionality to my app.
I have no problem locally, the app seems to run and authenticate users fine. The problem is when I deploy the production version to Heroku I get the error:
undefined method `find_by_auth_token!' for #<Class:0x007f35fbe37a78>
current_user
is defined in my ApplicationController
as:
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
This is my 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
And this is the User
model:
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
And in my 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
Why is this working in development but not production?
Ruby 2.2.1
& Rails 4.1.8
development: PostgresSQL 9.4.1
It's an old tutorial, rails 4 has different dynamic matchers
Rails 3
User.find_by_auth_token!(cookies[:auth_token])
Rails 4
User.find_by!(auth_token: cookies[:auth_token])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.