- Published on
Making a simple blog application in Rails with Devise
In part 1 of this post, we created a simple Rails application and set up devise for user authentication. In this post, we will continue with the application we had built in the previous post and convert it into a fully functioning blog/note taking application.
Tasks
Before we start building, let us take a moment to plan what all we actually need to achieve (Its also a good software engineering practice to extensively plan out your work even if your urge is to just start coding).
Right now in our application we just display “Hello World!” and have a sign up form. If the user has signed in, we display their email address. Let’s see what we can do next:
- Write a migration to create a new
notes
table. - Write the required controller, model and views for
notes
- Link
notes
withusers
with ActiveRecord associations so that a user has different notes and each note belongs to a user. A user should only be able to access notes they’ve created themself. - Make the notes accessible only if the user has signed in.
Adding the notes functionality
Let us do some Rails magic to generate a whole bunch of stuff for us in one go. Run the following command from your terminal to generate a scaffold for notes
in your application. It will generate all the migrations, controller, model and all the view files required for implementing CRUD functionality for notes. We can edit these autogenerated files to add our own functionality.
bundle exec rails g scaffold notes title:string body:text user:belongs_to
Run the migration and go to http://localhost:3000/notes in your app and you will be able to see the notes CRUD that the scaffold command generates for us. Let us make a few changes in the generated code.
-
Add the following callback to
NotesController.rb
before_action :authenticate_user!
The
authenticate_user
method comes from devise and lets us make sure that the actions in the controller to which this callback is added can only be called if there is a user currently signed in. If you try to access/notes
after adding the line, you can see that you’ll be redirected to the sign in page, if you aren’t already signed in. Pretty cool, right? Now try imagining how you’d implement theauthenticate_user
method from scratch as an exercise. -
Replace all instances of
Note
withcurrent_user.notes
inNotesController
We do this because by default the controller deals with all the records of the Note class when calling actions like index, etc. Replacing it with
current_user.notes
makes it so that each user is only shown notes which belongs to them. Keep in mind this is a very simple form of resource authorization and you might wanna look into gems like Pundit if your application requires complex authorization policies, like users should be able to see all comments in a note, but only the creator should be able to edit/delete the comment and so on -
Define the
has_many
association in theUser
modelhas_many :notes
-
Now let’s make two small changes in the UI
Replace the contents of
app/views/home/index.html.erb
with the following. Now we are redirecting the users to/notes
if they have signed in. If not they cannot access the notes page, and will be asked to sign in first.<% if user_signed_in? %> <script type="text/javascript"> window.location.href="/notes" </script> <% else %> <%= link_to "Sign in", new_user_session_path %> <p>Hello World!</p> <% end %>
Add the following to
app/views/notes/index.html.erb
<div> Welcome <%= current_user.email %> </div> <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
These are the lines we had added in the
index.html.erb
file of the home view in the last post to show the details of the signed in user. We now have it inside the notes page, to which the users will be redirected to after they sign in.
Conclusion
With this, you will have a very basic application where users can sign up and manage notes under their accounts. This application is only a bare-bones proof of concept. The aim of these guides is not to build a production ready blog application, but to educate the reader about user authentication in Rails with devise. If you’ve followed this post so far and tried everything on your own, you’d have gotten a pretty good idea of how to use devise and all the different helper methods that comes with it.
As a final exercise, I'd highly recommend you go through the devise GitHub repository and study the readme file to get a better understanding of devise and also read about all the helpers and methods we haven't discussed in these posts.
If you're interested in learning more about deploying your Rails application, check out the Rails in Production series of posts to delve into the devops side of Rails.