Rails Project Management AJAX Refactor

Now with 100% more AJAX

ajax
No, not that AJAX.

About one month ago, I finished version 1 of Rails Project Management, my first full scale web application, for my Flatiron School Ruby on Rails assessment. My next assessment was to refactor the program with Javascript and implement dynamic features only possible through JQuery and a JSON API. I decided to focus on refactoring some of the CRU functionality for Projects, Tasks, Comments, and Notes so they use AJAX instead of full page refreshes. This project was also a great learning experience for using HandlebarsJS, a Javascript templating tool. While the “remote: true” pattern would have been easier, the assessment required that we not use it.

In this post I’ll do a deep dive into how and why I refactored each feature.

Comments

This was the first feature I tackled. Originally, when a user created a comment, the page would refresh and Rails would render the new comment to the comment feed on the task page.  To edit a comment, a user would have to click on the edit button, which would take them to the comment edit page. The user could then edit the comment text on this page. On submission they would be redirected to the task page. This step is unnecessary and doesn’t make for a good user experience.

The refactored Comment CRU process users AJAX for a more dynamic and seamless user experience. When a user creates a comment, a few things happen:
– The form’s default behavior is prevented
– Form values are serialized and (along with the URL) are passed to another function
– The next function executes an AJAX POST request to the appropriate controller action with the arguments
– Rails creates a new Comment in the database, and renders a JSON response
– On success, a new Comment object is created with the response
– The Handlebars template is rendered with the Comment attributes and injected into the page via JQuery.

Note: the Handlebars templates are compiled on page load, so they are ready for use when the AJAX requests are submitted.

Clicking the ‘Edit’ button sends an AJAX GET request to the application, which returns a JSON response. A Comment object is created in Javascript with the response. Then, a different Handlebars template is rendered with the Comment attributes and injected into the page. This template replaces the comment content with an editable form.

Submitting the newly rendered form sends an AJAX POST request to the application. Much like when we created the first comment, another Comment object is created with the response. The first Handlebars template is rendered with the Comment attributes and then injected back into the page.

Notes

Notes function similarly to Comments, however there are a few differences. On the Notes index page, only Note titles are rendered by Rails. When a user clicks “View”, the Note content is loaded to the page via an AJAX GET request. Once loaded, the user can edit the Note content and title in place (similar to Comments). Form information is submitted via an AJAX POST request. It is then rendered on the page via an AJAX GET request and a Handlebars template.

Tasks

For Tasks, I focused on the refactoring the filtering options. In the first version of RailsPM, filtering was hacked together using individual routes, controller actions, and views. For example: Viewing all complete project tasks required it’s own route, controller action, logic, and rendered view. This solution is not flexible, scalable, or good for the user experience. User also didn’t have the option to sort by whether they were a task owner or assigned to a task, which is critical.

The refactored Task filtering uses AJAX, JQuery, and Handlebars templates to render JSON responses. I used this solution for both the All Tasks view and Project Tasks view.

I started by upgrading the filter buttons to use AJAX requests so the appropriate tasks would be loaded onto the page, instead of sending the user to an entirely new page. After I figured out how to load the tasks using AJAX, I decided the entire filtering system would make more sense if it was a form instead of buttons tied to specific routes, actions, and views.

Rails Project Management Tasks Filtering Form
Task filtering form

The filtering buttons have been replaced with a form. This form submits an AJAX GET request to the application. For each task in the response, a Task object is created, rendered into a Handlebars template, and injected into the page using JQuery. I’m not completely happy with the logic I used for the form filtering but it’s flexible enough that I could add more filtering options without too much work. In the future I would like to revisit this and see how I can make the logic cleaner and more flexible.

Projects

I applied the same filtering process for tasks to projects. At this point, I already switched over to using the forms so I was able to quickly implement this; however, since project collaborators and assigned task users are different, I used different functions and methods. However, the base functionality is the same: the form  parameters are sent to the application via an AJAX POST request, and the server responds with JSON. For each project in the response, a Project object is created and a Handlebars template rendered with that Project’s attributes. It is then injected into the page using JQuery.

Other Stuff

Users can now upload a profile image to their user account. This was accomplished using Paperclip and Imagemagick.

I also scrapped the admin system I had previously developed and used ActiveAdmin instead for the admin panel.

Rails PM Active Admin Dashboard
Rails PM Active Admin Dashboard

Any feedback or suggestions? Leave them in the comments below or shoot me an email at mail@mattcassara.com.

Leave a Reply

Your email address will not be published. Required fields are marked *