Wednesday, November 14, 2007

Rails Coding Standard

The small team I'm part of work on a large Rails project (in complexity and scope). We've all got quite contrasting backgrounds: PHP hackers, J2EE pattern junkies & legacy spaghetti coders.

I've found some recurring issues that arise relating to code quality, so have set out to write a mini-code standard.


  1. IN ESSENCE: ALL CODE SHOULD BE READABLE!

  2. DO NOT OPTIMISE for performance - OPTIMISE FOR CLARITY OF CODE

  3. STYLE: use 2 spaces for indent (not tabs)

  4. STYLE: Line up hash arrows for readability

  5. STYLE: put spaces around => hash arrows

  6. STYLE: put spaces after ',' in method params - but none between method names and '('

  7. VIEWS: use HAML for views

  8. VIEWS: break up the structure with white space to help readability - VERTICALLY TOO!

  9. VIEWS STYLE: Rely on structure of page, without having to insert messages or new components...

    • Example: Effect to visually highlight then drop out an existing element rather than flash a message

    • Example: Highlight newly added row rather than a message about it



  10. AVOID logic in views - they should be simple

    • put html generating logic into helpers

    • instead of inline ruby logic, add to models (filtering, checking)



  11. NEVER use ActiveRecord models in migrations unless you re-define them within the migration

    • ...otherwise the migration fails when you later remove/rename the AR class

    • BETTER SOLUTION: use bootstrapping until deployed!!!



  12. AJAX only for sub-components of an object, and avoid over-use



Now the problem with code standards, is that they need to be adhered to, or they're totally useless. That's why the above is very short and easy to comprehend in one quick sitting.



What would you add or remove?

2 comments:

Nikc said...

re #11

what do you do if your migration has to alter the data in some way?

Adz said...

In that case, we DO use AR models, but redefine them within the migration class scope.

This avoids any problems when migrating a fresh database.

Example:
In migration 003 you create a row representing the 'admin' user in the 'users' table, but in migration 010 you decide to rename the 'users' table to 'accounts'.

In our case, everything seemed fine until I nuked my db and re-ran migrations - only to find them fail half way through - because of a migration written last week!

As an aside - within the migration you won't have access to dynamic associations. That's good, since they could change too!

Deal with it by assigning the foreigm keys directly.

Example:
# Not: article.user = user
article[:user_id] = user.id