Search code examples
rubyactiverecordsinatrasinatra-activerecord

Methods to validate whether user is logged in aren't working for Sinatra Application.


I have two helper methods below.

  helpers do
    def logged_in?
     !current_user.nil?
    end

  def current_user
   @current_user ||= User.find(session[:user_id])
  end

I am using these methods to authenticate whether a user is logged in or if they need to log in or create an account. On my index page I have two routes that take me to either a log in page or a create user page. These routes are shown below.

HTML View

<html>
<head>
 <title>Simple Meal Prep</title>
   <link href="https://fonts.googleapis.com/css?family=Caveat" 
    rel="stylesheet">
   <link rel="stylesheet" type="text/css" href="/stylesheet.css" />
</head>
<body>
 <h1 id="landing_page_title">Welcome to Cookbook</h1>
 <h2 id="site_logline">A Simple App to keep track of your recipes</h2>
 <br></br>
 <a id="login_button" href="/login">Login</a>  <route 1>
 <br></br>
 <a id="signup_button" href="/signup">Sign Up</a> <route 2>
</body>

Corresponding User Controller Routes

class UserController < ApplicationController

 get '/user_home' do
  if logged_in? then erb :"/users/user_home" else redirect '/' end
 end

 get '/login' do
  if logged_in? then redirect to '/user_home' else erb :"/users/login" 
   end
 end
end 

The error that I am getting is when I click on my login button I get a sinatra error stating "ActiveRecord::RecordNotFound at /login Couldn't find User without an ID". Looking at the backtrace from sinatra I don't believe that my logged_in? method is working correctly. I'm wondering if anyone has any suggestions on what steps to take next or sees something that I'm not seeing. I can include any additional code or schema if needed. Thanks.


Solution

  • Use find_by(id: session[:user_id]) instead of find(session[:user_id]).

    find raises an error if a nil id is passed, or no matching record is found. find_by doesn't raise an error in either of these situations.

    Since your code allows for the result of this query to be nil (the @current_user variable will be nil, and so will the return value of the current_user method) it seems this one change will solve your problem.