前提・実現したいこと
RailsでGemなしのログイン機能を実施しようとしていますが、画面で
undefined method `authenticate' for nil:NilClass
のエラー が発生しています。
bcryptもインストールし、Userコントローラーにhas_secure_passwordを記載していますが
SessionsControllerでエラー になってしまいます。
解決策が見つからずつまっています。
わかる方いらっしゃいましたらよろしくお願いします。
発生している問題・エラーメッセージ
NoMethodError in SessionsController#create
undefined method `authenticate' for nil:NilClass
該当のソースコード
SessionsController.rb
class SessionsController < ApplicationController skip_before_action :require_sign_in!, only: [:new, :create] before_action :set_user, only: [:create] def new redirect_to tasks_path if signed_in? end def creates if @user.authenticate(session_params[:password]) sign_in(@user) redirect_to tasks_path else redirect_to login_path, :alert => "無効なユーザー名/パスワードです。" flash.now[:danger] = t('.flash.invalid_password') render 'new' end end def destroy sign_out redirect_to login_path end private def set_user @user = User.find_by(user_id: session_params[:user_id]) rescue flash.now[:danger] = t('.flash.invalid_userid') render action: 'new' end def session_params params.require(:session).permit(:user_id, :password) end end
User.rb
class User < ApplicationRecord has_secure_password validates :user_id, presence: true, uniqueness: true validates :password, presence: true def self.new_remember_token SecureRandom.urlsafe_base64 end def self.encrypt(token) Digest::SHA256.hexdigest(token.to_s) end has_many :tasks, dependent: :destroy end
class ApplicationController < ActionController::Base before_action :current_user before_action :require_sign_in! helper_method :signed_in? protect_from_forgery with: :exception def current_user remember_token = User.encrypt(cookies[:user_remember_token]) @current_user ||= User.find_by(remember_token: remember_token) end def sign_in(user) remember_token = User.new_remember_token cookies.permanent[:user_remember_token] = remember_token user.update_attribute(:remember_token, User.encrypt(remember_token)) @current_user = user end def sign_out @current_user = nil cookies.delete(:user_remember_token) end def signed_in? @current_user.present? end private def require_sign_in! redirect_to login_path unless signed_in? end end
Gemfile
ruby '2.6.2' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.2.2', '>= 5.2.2.1' # Use mysql as the database for Active Record gem 'mysql2', '>= 0.4.4', '< 0.6.0' # Use Puma as the app server gem 'puma', '~> 3.11' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' gem 'rails-i18n', '~> 5.1' gem 'kaminari', '~> 0.17.0' # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2' # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.5' # Use Redis adapter to run Action Cable in production # gem 'redis', '~> 4.0' # Use ActiveModel has_secure_password gem 'bcrypt', '~> 3.1.11' # Use ActiveStorage variant # gem 'mini_magick', '~> 4.8' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.1.0', require: false
補足情報(FW/ツールのバージョンなど)
OS mac
Rails 5.2.2.1
ruby 2.6.2