Now that I’ve got a few Ruby on Rails projects under my belt, I finally feel qualified to comment on Rails front-end coding conventions. As a UI specialist coming to Rails from the JSP world, I find a lot of room for improvement in the RoR approach to view-layer code. I love working on the non-view aspects of RoR projects, but I find I’ve got to do tons of cleanup at the ERB layer. Expect to see some open-source components from Pathfinder to help ease this pain. In the meantime, let me articulate my pain points:
If I’m filling a front-end role on a Rails project, most of the files I need are in /app/views and /public. I dig that. Likewise, I appreciate the underscore naming conventions for partials. However, I wish /layouts weren’t just another subdirectory of /app/views. Layouts are inherently different from standard view templates. A better hierarchy within /app/views would help drive this home. Likewise, I wish partials and full templates each had their own directory within a specific controller’s view folder. That would help keep directories manageable on big projects. The /public directory, on the other hand, offers just the right amount of organization.
Markup and styles
Scaffolds are awesome for rapid prototyping, but the markup and styles they spit out reflect a standard of front-end coding that’s several years out of date. Plenty of plugins tackle this very problem, but I’m disappointed to find so little attention to view-layer code from the core version of such a respected application platform.
In an ideal world, a platform famed for its convention-over-configuration approach would ship with a decent reset.css and a solid baseline stylesheet with reusable utility styles that rely on class rather than id attributes to work their magic. I’m not talking about layout so much as simple problems that have long been solved in the web standards world: pure CSS pipe-delimited lists, table-free form layouts and the like.
So much Rails development is about tweaking the defaults just enough to achieve the results you need. That means lots of crappy auto-generated markup ends up in production. Rails can’t be all things to all people, but it would be cool if it didn’t pump out antiquated UI code by default.
Macros and view-logic encapsulation
Tab-based templating systems make it easy to separate view logic from application logic. Whether you’re using JSTL or a custom tag library, JSP 2.0 offers a specific syntax for templating that’s different from the syntax used for model and controller logic. Sure, JSP tags compile down to Java, but they look different from regular Java. And sure, you can use scriptlets in JSP, but you don’t have to.
In Rails, however, ERB looks like plain old Ruby code. It’s hard to tell at a glance whether the Ruby contained in a template is doing view stuff or jumping the shark to tackle controller and model stuff. This makes it very difficult for either humans or automated tools to do sniff tests on Rails code for separation of concerns at the view layer.
Helpers exacerbate the problem. In JSP, if you need to create a view-layer macro, you do it as a tag. In Rails, you do it as a helper. But those helpers live in the same place as other, unrelated helpers from the controller. The result is a mixture of view code and controller code within the same directories and even the same files.
If experience has taught me anything, it’s that controller logic and even model logic like to leak into the view. Without strong conventions to prevent this, it’s too easy to compromise your MVC architecture and hinder the maintainability of your application. JSP offers better encapsulation of the view layer – a clear advantage.
Of course, I’m still a Rails noob and have probably missed all sorts of best practices that could help ameliorate the bad and accentuate the good. Let me know in the comments!