company-logo

From JSP to Ruby on Rails: First thoughts on front-end coding conventions

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:

Code organization

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.

JavaScript

I’ve posted before about my experiences dropping jQuery into Rails and making it work. I’m not a huge fan of the tight coupling between a specific JavaScript framework and the core server-side framework. Nor do I love the lack of built-in progressive enhancement on many of the Rails Ajax helpers. I get why it’s attractive to people without dedicated front-end resources. But for anybody who wants to do a really sophisticated behavior layer, Rails Ajax helpers are more of a hindrance than a help. jRails and other projects offer a way to drop jQuery into a project and still access the Rails Ajax helpers, but I’d love to see a different approach to sophisticated Rails Ajax, one that doesn’t create apps that break when JavaScript is unavailable.

Conclusions

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!

  1. Robert Pierce Reply

    Hi Brian, thanks for an interesting, insightful writeup. It sounds like you may find haml/sass/blueprintcss useful/delightful in your further Rails travels.

    Haml/Sass: http://haml.hamptoncatlin.com/
    Compass(blueprint integration): http://github.com/chriseppstein/compass/tree/master

  2. JONNALAGADDA Srinivas Reply

    Nice analysis! On a couple of reasonably large Ruby on Rails projects (over 100,000 lines of Ruby code), I have seen views accumulate business logic inseparably. For comparison, liftweb has “views with no controller/model logic” as one of its core principles. DPP admits, though, that the opposite (view logic creeping into controller) is more difficult to stop.

  3. Piotr Sarnacki Reply

    About javascript. I think that creating accessible and unobtrusive apps with ajax is a matter of not mixing javascript code and view code. So anyway, I don’t use rails helpers at all.

    I try not to use rails js callbacks either, for keeping my javascript out of rails. But this one isn’t necessary for unobtrusive app.

  4. charlie bowman Reply

    One solution I’ve used is to create a presenter for each one of the displayable models. Each presenter can follow the same inheritance structure as the model and can really help to clean up those nasty helper methods.

Leave a Reply

*

captcha *