Rails: In The Pursuit Of Writing Boring Code

Brian Emory
Brian Emory | Web Developer
5 min readMay 1, 2017
Can’t talk about Rails without a cat right?

Putting RailsConf talks to use

I attended RailsConf in Phoenix last week. It was a wonderful experience even as introverted as I am. It was great meeting people I knew from their podcasts, DHH, fellow Flatiron students, and other developers during lunch. The talks were very informative and really got me thinking about ways I can be a better developer.

The first talk I attended was thoughbot’s Derek Prior’s In Relentless Pursuit of REST. The whole talk all I could think about is how I was doing everything wrong in my Schedule App. Well, not everything. There were plenty of places I did not use REST and now I was feeling awfully guilty about it. His closing three slides form a motto to code by: Be CRUDdy, Be Boring, Be RESTful.

I was again reminded about the importance of REST in michelada.io’s David Padilla’s talk Tips and Treats for New Developers.

Combining these two I have a new motto: Be CRUDdy, Be Boring, Be RESTful All the Time.

Time to get RESTful

My Schedule App that I have been building for my wife, has some very unRESTful practices. The schedules_controller has a set_shifts action to create and edit a schedule’s shifts. It also has actions add_employees and remove_employees for associating them with a schedule. There is a print_schedule action for showing the schedule with minimal styling. The employees_controller has an action for toggling their status. There is a lot to change but with full test coverage, I can go to town without worry of breaking something.

The schedules and shifts controllers

The first change is the one I thought would be the trickiest. Moving the set_shifts from the schedules_controller to the create action in the shifts_controller. This will be a two stage process. Step one, completed in this commit, was not as bad as I thought. It was essentially moving private methods, updating routes, and changing a few things in the views.

The index action is basically a combination of new and edit. I have mixed feelings about this but ultimately think it is fine. When editing or creating shifts, it is being done in bulk. You are not visiting a page to create or edit one shift. It is being done for every single shift, every single day, every single employee. The index action usually shows all the model, and this is all the shifts.

For step two of this process, I was thinking about splitting the create action into create and update actions. This is another one I have mixed feelings about and may not make the change. When you click Set schedule on a schedule’s show page, your form allows you to create and update shifts on the same page. Now that I think about it, you can also delete shifts at the same time. I will revisit this later for potential refactoring.

Adding and removing employees

After making the above changes, I was feeling pretty good about this one. Adding and removing employees from a schedule was creating and destroying the associations between the two. I would create an associate_employe_controller with a create and a destroy action. This would handle the previous add_employee and remove_employee actions in the schedules_controller.

This commit was pretty straightforward. It had the above changes, updates to the routes, and changes to the url paths in the view. All tests are passing so time to move to the next section.

Employee status toggle

Following the steps from the previous changes, I first started with the controller. I created status_controller to handle the toggle functionality with its update action. I moved the code over from the employees_controller toggle_status action.

By default, all employees start with a status of active. This allowed me to use only the update action to handle toggling an employee’s status. You can see the full commit here.

Print schedule

Alright, down to our final non-CRUDdy action! When you viewed a schedule, you could click the “Print schedule” button to see the print schedule page. It seems all well and good except that the page is exactly like the show schedule page minus the buttons at the top. It gets an added variable, @printable_view, which hides all the employees’ availability slots. There was no reason to have this be a separate view.

In this commit, I removed the print schedule page, action, and route. Now when you hit “Print schedule”, a param called print: true is passed into the show action which sets the @printable_view variable. I now have the same functionality without what was essentially a duplicate page.

The other thing I did was change how the page renders buttons. The schedule show page has buttons for “Adding/Removing all employees”, “Set schedule”, and “Print schedule”. To control the viewable buttons, I created a couple of helper methods.

The which_buttons? method shows the “Adding/Removing all employees” and “Set schedule” buttons if admin == schedule.admin && @printable_view.nil?. The print_view? method shows the “Print schedule” button only if @printable_view.nil?.

The last thing I changed was in the print view. I had the words “Printable schedule” show at the top of the page where the buttons use to be. My test for this page would look for that text. I removed the text from the view and edited the test to expect the page to not have the test “Set schedule”. If the helper method is working, this will not show on the page.

All green

After each set of changes, my test suite was still green. Since I had 100% coverage, I could be confident is working. This was yet another great example why testing is so important. There is more work to be done on this app but I am feeling pretty good with it being RESTful.

Follow me on Twitter @thebrianemory. Follow me here, click the green heart to show some love, leave a comment, and get in touch!

--

--

Brian Emory
Brian Emory | Web Developer

Backend Software Engineer (Ruby/Elixir). Giraffe-like qualities. I enjoy video games, bad movies, hard ciders, and pizza.