Letting the users delete posts
Deleting posts
Let's also give your app the ability to delete a post directly from your app, if you don't want anyone to be able to access it anymore.
Adding the delete link
First we need a delete link for each post we display. For this go to app/views/posts/index.html.erb
and after the line that mentions the email of the author add this line:
<p><%=link_to("Delete", post_path(post), method: :delete) %></p>
This adds a link with the text Delete, that will go to the post_path
of our post and use on it the method delete.
Adding the controller action
If you save, refresh the browser page, and click on Delete, as usual when adding new functionality to our website you will get an error.
Let's define what action our posts controller should execute when clicking delete. In /app/controllers/posts_controller.rb
type:
def destroy
@post = Post.find(params[:id])
@post.destroy
redirect_to posts_path
end
Checking that everything works
Save everything and try adding and deleting posts in your app. Voilà!
Restricting access
We're getting close to the end of the first day, but before we finish there's one more thing to consider. We don't want anyone to be able to access everything stored in your app. For example, we would like to restrict the data modification to the author of the post.
Let's explore a few restriction scenarios and their solutions.
Using controller filters
First, you may not want people who are not logged into your app to view the posts. At this stage, if you open an incognito window in your browser and go to localhost:3000/posts
you will still be able to see all the posts.
Opening the link in an incognito window in your browser allows you to use the application as an unauthenticated user. Thus, you can have one browser window where you are logged in and a window where you view your app as it is seen by the public.
To solve this, type at the very beginning of posts_controller.rb
, before all the other actions:
before_action :authenticate_user!
before_action
stops whatever Rails is doing. :authenticate_user!
is a Devise instruction that tells Rails if anyone is signed in. If not, the user will be redirected to the /users/sign_in
page.
Restrict delete action to owners
A second case of restricting access is that you don't want users to delete other people's posts. The way we will do it is by showing the Delete button for each post only if the current_user
is the user who created the post.
In /app/views/posts/index.html.erb
change the line with the delete link with the following code:
<% if current_user == post.user %>
<%=link_to("Delete", post_path(post), method: :delete) %>
<% end %>
The code above, in a Ruby tag that doesn't return anything (<% %>
) checks if the current_user
is equal to the posts's creator user. If true, the following block of code will display(<%= %>
) the Delete link.
Checking that everything works
To check if it works open again an incognito window in your browser, go to localhost:3000/users/sign_up
and create a new account. When you visit the localhost:3000/posts
page, there are no Delete links near the posts that were created with your first account.
If you now create a post with the current user account, you will see a Delete link for it.