How to Hide Form Elements from Non Admin Users
In this guide we are going to create functionality that will ensure that only admin users are able to see the radio buttons in our form.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

In this guide we are going to create functionality that will ensure that only admin users are able to see the radio buttons in our form.

Let's go to our approval_workflow_spec.rb file and add two new test cases with the descriptions:

  • "it has a status that can be edited on the form by an admin"
  • "it cannot be edited by a non admin"

If you use an x before an it block it will mark the test case as pending, so rspec won't run it.

Since both these test cases require a visit to edit_post_path, let's put it in a before block. Let's update the tests to look like this:

# spec/features/approval_workflow_spec.rb

describe 'edit' do
  before do
    @post = FactoryGirl.create(:post)
    visit edit_post_path(@post)
  end

  it 'has a status that can be edited on the form by an admin' do
    choose('post_status_approved')
    click_on "Save"

    expect(@post.reload.status).to eq('approved')
  end

  xit 'cannot be edited by a non admin' do
  end
end

In the pending test case, we are going to logout the admin user and log in a regular user. Then, we'll have the test access the page and we're expecting it not to have the content: "Approved". I chose this test case because when the text "approved" is not there, it means the radio buttons are not visible to the user. The code for this is:

# spec/features/approval_workflow_spec.rb

it 'cannot be edited by a non admin' do
  logout(:user)
  user = FactoryGirl.create(:user)
  login_as(user, :scope => :user)

  visit edit_post_path(@post)

  expect(page).to_not have_content('Approved')
end

If you run rspec, you'll get this error.

large

To fix this, let's create a partial called _status.html.erb, and copy the status code from _form.html.erb to it.

<!-- app/views/posts/_status.html.erb -->

<div class="form-group">
  <%= f.radio_button :status, 'submitted' %>
  <%= f.label :status, 'Submitted' %>

  <%= f.radio_button :status, 'approved' %>
  <%= f.label :status, 'Approved' %>

  <%= f.radio_button :status, 'rejected' %>
  <%= f.label :status, 'Rejected' %>
</div>

In the _form.html.erb partial we'll call the _status.html.erb partial in place of where the radio buttons used to be. We'll also pass in the form block variable as a local variable.

<!-- app/views/posts/_form.html.erb -->

<%= render partial: 'status', locals: { f: f } if current_user.type == 'AdminUser' %>

I don't love this implementation because we're hard coding the word "AdminUser", but we'll refactor this later. For right now we'll focus on getting the feature working properly.

If you run the tests you'll see that they're all passing.

Let's look at it in the browser.

large

If you log in as a regular user and go to the edit page, you can't see the radio buttons. But if you login as an Admin user you can see the radio buttons.

Resources