Implement Permission Structure into Nav Bar Elements
Learn how to update the navigation bar to match the permissions provided for employees and managers.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

If you go to the admin dashboard, you can see that they have access to "Entries" and "Request Overtime", which they don't really need. This is bad user interface as you'll have to give buttons only if they are going to use them.

In this video, we're going to remove these links and also, refactor some code.

Open application_helper.rband create two new methods - employee? and admin?. As you may have guessed, these methods are going to help us figure out which type of user is currently logged in.

# app/helpers/application_helper.rb

def employee?
  current_user.type == 'Employee'
end

def admin?
  admin_types.include?(current_user.type)
end

Now, let's use these methods in _nav.html.erb. Before that, I think we can move some of the code in our _nav.html.erb to another partial. So, create a file in shared and call it admin_dropdown.html.erb. In this file, let's move our link.

<!-- app/views/shared/_admin_dropdown.html.erb -->

<li>
  <%= link_to "Admin Dashboard", admin_root_path %>
</li>
<li class="divider"></li>

Call this partial in _nav.html.erb like this:

<!-- app/views/shared/_nav.html.erb -->

<li class="dropdown pull-right">
    <a href="#" data-toggle="dropdown" class="dropdown-toggle">Options<strong class="caret"></strong></a>
  <ul class="dropdown-menu">

    <%= render 'shared/admin_dropdown' if admin? %>

    <li>
      <%= link_to "Logout", destroy_user_session_path, method: :delete %>
    </li>
  </ul>
</li>

Now, test this in the browser. I think everything is good so far.

Next, we'll create a partial that shows "Entries" and "Request Overtime" only for regular employees. Let's call this partial _employee_nav_items.html.erb. Now, we can move all the display code for these two tabs and put them in the new partial. So, our partial should be:

<!-- app/views/shared/_employee_nav_items.html.erb -->

<li class="<%= active?(posts_path) %>">
  <%= link_to "Entries", posts_path %>
</li>

<li class="<%= active?(new_post_path) %>">
  <%= link_to "Request Overtime", new_post_path, id: 'new_post_from_nav' %>
</li>

Next, make sure to add this partial call to our _nav.html.erb file.

Also, for the audit_log tab, we don't have to use the policy anymore as we can use admin?

<!-- app/views/shared/_employee_nav_items.html.erb -->

<% if current_user %>
  <ul class="custom-nav nav nav-tabs">
    <li class="<%= active?(root_path) %>">
      <%= link_to "", root_path, class: 'glyphicon glyphicon-home' %>
    </li>

    <%= render 'shared/employee_nav_items' if employee? %>

    <%= render 'shared/audit_log_tab' if admin? %>

I think the code is a lot cleaner now.

If we check on the browser, everything looks great!

large

Let's also rspec to ensure we didn't break anything. And we have an error.

large

Let's see what this error is. Open post_spec.rb and scroll to line #45. Since we don't need a link to the homepage for everybody, I think we should create and log in a regular user.

If we run rspec again, everything passes.

# spec/features/post_spec.rb

describe 'new' do
  it 'has a link from the homepage' do
    employee = Employee.create(first_name: 'Employee', last_name: 'Authorized', email: "employee@example.com", password: "asdfasdf", password_confirmation: "asdfasdf", phone: "5555555555")
    login_as(employee, :scope => :user)
    visit root_path

    click_link("new_post_from_nav")
    expect(page.status_code).to eq(200)
  end
end

Resources