Create a Blog Application with Ruby on Rails 7. Fifth Part: Implement Authorization
In Ruby on Rails Sep 10, 2022
Updated on Dec 17, 2023
In this last post from this series, we will implement a simple authorization in our blog application.
All Parts:
- Create a Blog Application with Ruby on Rails 7. First Part: Create the User Resource
- Create a Blog Application with Ruby on Rails 7. Second Part: Create a Post Model and a Posts Controller
- Create a Blog Application with Ruby on Rails 7. Third Part: Implement User Authentication
- Create a Blog Application with Ruby on Rails 7. Fourth Part: Performing Operations on the Post Resource
- 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.