Talk Notes: Rails Sustainable Productivity by Xavier Shay
Here are my notes on Xavier Shay’s awesome video on sustainable productivity in Rails. I agree wholeheartedly with all of his points, and although they’re not particularly new, it’s nice to hear from someone with real world perspective on maintaining a large Rails project.
- Rails does not make data integrity a priority, so be conscious of it and take the effort. Ideally the framework will evolve in this direction eventually.
- validates_uniqueness_of doesn’t validate uniqueness with concurrent access – you need db constraints (unique indexes, foreign keys, etc). At the same time, Rails doesn’t provide a good built in way to error handle constraint violations.
- Rails encourages poor practice with database because things like t.references in migrations doesn’t add foreign keys.
- (personal note) I have seen many Rails projects completely ignore database keys. I like the old adage that your database will outlive your application. Put constraints where they belong.
- Consistency is incredibly important, and is more so when you have a large team. If you create two ways of doing one thing, the next developer has to scratch his head. Don’t duplicate code or concepts, design for reuse.
- Don’t pepper third party dependencies in your code. Design layers of abstraction so that all third party access is in one spot, easy to change. Use reification – start naming concepts rather than implying them with conditional logic (e.g. the Null Object pattern).
- “Fail your build for basic style, complexity, and readability violations.” Don’t let people check in stuff with bad whitespace, complex methods, etc. Make it part of the continuous integration cycle. Bad code spawns more bad code. Easier to prevent in the first place than untangle later. (see: cane, also metric_fu)
- Self-documenting code is awesome, but documentation should be used on a class level to describe how the class figures into the bigger picture. I’m a huge fan of this idea, and don’t do it enough myself.
- Rails unit/functional/integration test definitions are different from everywhere else in the world. They tell you how to organize code but are not useful, leading us to have “fast spec” vs “slow spec”. This is bad. A unit test should not touch the database, filesystem, etc. Unit tests should be fast and without dependencies, integration tests specify boundaries, acceptance tests make sure the system works.
- (Personal note) At Crowdcast we have been working purely with fast-spec lately, even stubbing out dependencies in our controller tests so we can blazing fast TDD our code through the entire stack, relying on a single high level acceptance test that makes sure everything connects correctly, and stubbing everything at lower levels.
Videos are awesome but not everyone has the time. I made these notes for myself but if people find them useful, I’ll try to continue blogging short summaries of talks that I watch. I hope others do the same, so we can save each other time :)