Search code examples
ruby-on-railsif-statementruby-on-rails-5

ActiveRecord::RecordNotFound in HomeController#index Couldn't find User with 'id'=


ERROR: when logout.

I'm trying to display _admin_user_header partial using an if statement for when 'admin' is logged_in:

Extracted from: _header partial.

<div class="collapse navbar-collapse d-flex justify-content-end">
  <% if(current_user && current_user.role == 'admin') %>      <== this 
    <%= render partial: 'admin_user_header' %>                <== 2 lines 
  <% elsif(logged_in?) %>
    <%= render partial: 'registered_user_header' %>
  <% else %>
    <%= render partial: 'anonymous_user_header' %>
  <% end %>
</div>

Doing <% if(current_user && current_user.role == 'admin') %> apparently works, but when I try to logout from the current_user account, I get this error:

ActiveRecord::RecordNotFound in HomeController#index

Couldn't find User with 'id'=
Extracted source (around line #25):

23      end
24
25      @current_user = User.find(session[:user_id])
26   end
27
28   def ensure_authenticated

Rails.root: 
/Users/dangerrg/Documents/....

Application Trace | Framework Trace | Full Trace
app/controllers/application_controller.rb:25:in `current_user'
app/views/application/_header.html.erb:8:in `_app_views_application__header_html_erb__900908384298268245_70228604326660'
app/views/layouts/application.html.erb:12:in `_app_views_layouts_application_html_erb___299989914533477205_70228570235680'

I've checked other posts answers with a similar problem, looking for solutions, and I tried different ways to accomplish this, but no success yet.

I also check my DB in the Rails console and all users have and :id with its respective value assigned to it.

In application_controller.rb

...

 helper_method :logged_in?, :current_user

 def logged_in?
   session[:user_id].present?
 end

...

 def current_user
   if(@current_user.present?)
     return @current_user
   end

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

...

In home_controler.rb this is the only method:

 def index
   @tips = Tip.most_recent
 end

I'll really appreciate any help on this. Thanks in advance.


Solution

  • current_user will work only if user logged in. After logout it clears out session[:user_id]. That's why you can not find a user.

    User.find(nil)
    

    Before you call current user method that queries DB try to check that session[:user_id] present. That will work:

    if(logged_in? && current_user && current_user.role == 'admin')
    

    or

    def current_user
      return unless logged_id?
    
      if(@current_user.present?)
        return @current_user
      end
    
      @current_user = User.find(session[:user_id])
    end
    

    I think the best option here is to wrap render in if(logged_in?) statement:

    <div class="collapse navbar-collapse d-flex justify-content-end">
      <% if(logged_in?) %>
        <% if(current_user && current_user.role == 'admin') %>      
          <%= render partial: 'admin_user_header' %>                
        <% else %>
          <%= render partial: 'registered_user_header' %>
        <% end %>
      <% else %>
        <%= render partial: 'anonymous_user_header' %>
      <% end %>
    </div>