Create a Blog Application with Ruby on Rails 7. Fifth Part: Implement Authorization

In this last post from this series, we will implement a simple authorization in our blog application.

All Parts:

  1.  Create a Blog Application with Ruby on Rails 7. First Part: Create the User Resource
  2.  Create a Blog Application with Ruby on Rails 7. Second Part: Create a Post Model and a Posts Controller
  3. Create a Blog Application with Ruby on Rails 7. Third Part: Implement User Authentication
  4. Create a Blog Application with Ruby on Rails 7. Fourth Part: Performing Operations on the Post Resource
  5. Create a Blog Application with Ruby on Rails 7. Fifth Part: Implement Authorization

Anyone can read our blog, so we users don't have to be authenticated to request the index and show actions.

But, to create, update, delete or publish resources, users must be authenticated. That's why we will define some private methods in our Posts controller.

The first method we'll add to our controller will redirect the user to the log_in_path. We'll use this method for our new action. If users want to publish a new post and they aren't logged in, we'll remind them that they need to be logged in to publish something new.

So let's write this method:

def not_logged_in
  redirect_to log_in_path unless current_user
  flash[:notice] = 'You must be logged in to publish.'
end

Now, let's set this method as a before filter, only for the new action. At the top of the Posts controller, put this line:

before_action :not_logged_in, only: :new

In the posts index view, let's link to the new post action only if there is a current user:

<p>
  <% if @_current_user %>
    <%= link_to "New post", new_post_path %>
  <% end %>
</p>

Next, we'll define another private method that will simply return a not found status code if there is no user in the session. We'll call this method not_found:

def not_found
  raise ActionController::RoutingError.new('Not Found') unless current_user
end

And, finally, we'll implement an incorrect_user method that finds the post and then return a not found status code if the current user is not the user who created the post:

def incorrect_user
  @post = Post.find(params[:id])
  raise ActionController::RoutingError.new('Not Found') unless current_user && current_user == @post.user
end

And we'll use these two methods as before filters for the edit, update, destroy, and publish actions:

before_action :not_found, :incorrect_user, only: %i[edit update destroy publish]

We can now delete this line:

@post = Post.find(params[:id])

in the edit, update, destroy, and publish methods.

In the post show view, let's display links to the edit, destroy, and publish actions only if the current user is the user who created the post:

<% if @post.user == @_current_user %>
  <%= link_to 'Edit', edit_post_path(@post) %>
  <%= button_to "Delete", @post, method: :delete %>
  <% if @post.draft? %>
    <%= link_to 'Publish', publish_post_path(@post) %>
  <% end %>
<% end %>

Conclusion

We created  a simple blog application that allows users to register and then publish and update posts. 

Post last updated on Dec 17, 2023