I'm using layout/_header.html.erb to create a navigation bar/log in and sign up bar to appear on everyone page of my app. It works fine until a user signs in and then I get a no method error (when a user is signed in, I want the "login" function to change to "logout"). I believe that this is something to do with not being able to call a method outside of it's own controller but I'm not sure how to go about fixing this, if anyone could point me in the right direction I'd be very happy.
Error message:
NoMethodError in Users#index
Showing /home/stephen/ruby/friendlyaccess/app/views/layouts/_header.html.erb where line #14 raised:
undefined method `user_type' for nil:NilClass
Extracted source (around line #14):
<div id="usernav">
<ul>
<% if user_signed_in? && @user.user_type == 'client' %>
<li><%= link_to "Edit Details", edit_user_registration_path %></li>
<li><%= link_to "Sign Out", destroy_user_session_path, :method => :delete %></li>
<% else if user_signed_in? && @user.user_type == 'company' %>
_header.html.erb:
<div id="navbar">
<table>
<tr>
<th><%= link_to "Home", root_path %></th>
<th><%= link_to "Service Index", users_path %></th>
<th><%= link_to "About Friendly Access" %></th>
<th><%= link_to "Contact Us" %></th>
</tr>
<div id="usernav">
<ul>
<% if user_signed_in? && @user.user_type == 'client' %>
<li><%= link_to "Edit Details", edit_user_registration_path %></li>
<li><%= link_to "Sign Out", destroy_user_session_path, :method => :delete %></li>
<% else if user_signed_in? && @user.user_type == 'company' %>
<li><%= link_to "Edit Details", edit_user_registration_path %></li>
<li><%= link_to "View Profile", show_user_path %></li>
<li><%= link_to "Sign Out", destroy_user_session_path, :method => :delete %></li>
<% else %>
<li><%= link_to "Sign Up", new_user_registration_path, class: "active" %></li>
<li><%= link_to "Sign In", new_user_session_path, class: "active" %></li>
<% end %>
<% end %>
</ul>
</div>
users_controller.rb:
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
if params[:search]
@users = User.search(params[:search].capitalize).order("company_name ASC")
elsif params[:company_type]
@users = User.search(params[:company_type]).order("company_name ASC")
elsif params[:letter]
@users = User.search(params[:letter]).order("company_name ASC")
else
@users = User.all.order("company_name ASC")
end
end
def show
end
private
def set_user
@user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:company_name, :company_type, :photo)
end
end
user.rb:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
mount_uploader :photo, PhotoUploader
before_save :capitalize_attributes
def self.search(query)
where("company_name like ? OR company_type like ?", "%#{query}%", "%#{query}%")
end
def capitalize_attributes
capitalizable = ["first_name","last_name", "city", "company_name"]
self.attributes.each do |attr,val|
#based on comment either of these will work
#if you want to store nil in the DB then
self.send("#{attr}=",val.strip.capitalize) if capitalizable.include?(attr) && !val.nil?
#if you want to store a blank string in the DB then
self.send("#{attr}=",val.to_s.strip.capitalize) if capitalizable.include?(attr)
end
end
end
Change your before_action :set_user
like below to allow index
action
before_action :set_user, only: [:index, :show, :edit, :update, :destroy]
to use set_user
method so that @user
will be available for index
.
OR
Use current_user
instead of @user
as @user
is not initialized for index action
.
<div id="usernav">
<ul>
<% if user_signed_in? && current_user.user_type == 'client' %>
<li><%= link_to "Edit Details", edit_user_registration_path %></li>
<li><%= link_to "Sign Out", destroy_user_session_path, :method => :delete %></li>
<% else if user_signed_in? && current.user_type == 'company' %>
<li><%= link_to "Edit Details", edit_user_registration_path %></li>
<li><%= link_to "View Profile", show_user_path %></li>
<li><%= link_to "Sign Out", destroy_user_session_path, :method => :delete %></li>
<% else %>
<li><%= link_to "Sign Up", new_user_registration_path, class: "active" %></li>
<li><%= link_to "Sign In", new_user_session_path, class: "active" %></li>
<% end %>
<% end %>
</ul>
</div>