Keeping your code clean and organized while developing a large Rails application can be quite a challenge, even for an experienced developer. Fortunately, there is a whole category of gems that make this job much easier.
For most people, dead/inefficient code will build up over time. Others will find themselves in a similar predicament when they take over someone else’s project.
Actually, my own experience with code cleaning/polishing gems stems from having to optimize someone else’s Rails application. Considering its size and complexity, manual code refactoring was bound to be tedious and time consuming, so I decided to help myself as much I could with third-party tools.
If you want to keep your code maintainable, secure and optimized, take a look at some gems that have been doing the job for me:
Traceroute is a route cleaning tool for Rails applications. It provides a simple rake task for checking which routes are mapped to non existing controller actions, and finds out which controller actions are not reachable.
You will also be required to keep your controller helper methods and various before/after filters private, since they shouldn’t be a part of the public API. It sometimes has problems with showing false positives on mountable engines, but they can be easily overlooked.
This is a nice tool used for finding bottlenecks of your applications. It does a live speed analysis of how long it took for the request to be processed and how much of that time it was doing various renderings, database queries and DOM loading. Just plug it into your Gemfile and you’ll get a small window in the upper left corner of your page, showing you all of these information.
This one particularly blew my mind. The bullet gem helps you kill all the N+1 queries, as well as unnecessarily eager loaded relations. Once you install it and start visiting various routes in development, alert boxes with warnings indicating database queries that need to be optimized will pop out. It works right out of the box and is extremely helpful for optimizing your application.
A security analysis tool for your Rails applications. It scans through your application and outputs a nicely formatted table of possible vulnerabilities. Security warnings are grouped according to their severity (High, Medium and Low). You can learn more about their meanings on brakeman’s list of warnings.
Note that even if you end up not having any warnings, it doesn’t mean that your app is secure, since brakeman sometimes overlooks some basic security pitfalls.
Security-wise, there is also a gem called bundler-audit, used for checking vulnerable versions of gems in your Gemfile.lock.
Deadweight is used for cleaning unused CSS selectors. You have to hand out a set of your application’s style sheets and HTML pages, and it will report which CSS selectors are safe to remove.
The gem won’t work out of the box in Rails, since most pages have dynamic content, but Jason Morrison from Thoughtbot wrote a blog post on how to create a Rack Middleware and integrate it into your test suite to collect all the HTML content in one place.
If you’re using precompilers such as Sass or Less, you should compile all of your style sheets and hand them out as simple CSS files to the deadweight task. It is recommended that you remove all the vendor/third-party css files (such as Bootstrap files and similar) since they will end up clogging your output.
Static code analyzer for finding Rails specific code smells. It offers a variety of suggestions; use scope access, restrict auto-generated routes, add database indexes, etc. For a full list of suggestions, check out the rails-best-pratices official page. Unfortunately, sometimes it reports lots of false positives, such as unused methods. Nevertheless, it contains lots of nice suggestions that will give you a better perspective on how to refactor your code and learn some best practices.
If you like the suggestions that rails best practices gives, you also might find Sandi Metz’s rules for developers quite interesting. You can check if your code complies to Sandi’s standards with the sandi_meter gem.
A Ruby static code analyzer which you can use to check if your code complies with the Ruby community code guidelines. The gem reports style violations through the command line, with lots of useful code refactoring goodies such as useless variable assignment, redundant use of Object#to_s in interpolation or even unused method argument.
A good thing is that it’s highly configurable, since the analyzer can be quite irritating if you’re not following the Ruby style guide 100% (i.e. you have lots of trailing whitespaces or you double quote your strings even when not interpolating, etc.).
It’s divided into 4 sub-analyzers (called cops): Style, Lint, Metrics and Rails. You can define which cops to use, as well as which files to exclude/include and tweak various other configuration options in a .rubocop.yml file.
A relatively new gem that wraps around three static analysis gems – Reek (ruby code smells), Flay (code duplication detection) and Flog (ABC metrics). It creates nicely structured HTML files so you can browse through your smelly code and start refactoring. Out of all of the mentioned static code analysis tools, because of it’s nice output, it’s most convenient to overview and comment with your colleagues.
If you’re working on an open source project or can afford to automate the process of running all of these static code analyzers on every commit, I would suggest using the code climate service. In case you decide to go down this route, I suggest reading “A Ruby on Rails Continuous Integration process using Github, Semaphore, CodeClimate and HipChat”, a blog post written by my colleague, Jan Varljen.
Most of the functionalities that the listed static code analyzers can offer you is already wrapped inside it. Besides code quality reports, there is an optional code coverage report (basically what simplecov does).
One thing to note is that you shouldn’t take each warning issued by these static code analyzers too seriously. Most of them will throw lots of stuff at you that you will probably never refactor because it will take you forever, and for some you just shouldn’t care (such as final newline missing or spruceing up your auto generated schema.rb). Sometimes they can generate lots of rubbish, but that can be prevented by doing code reviews on a regular basis and by tweaking their configuration options.