Why we don't use a Rails template
It seems like every six months someone in the Ruby on Rails community releases their Rails template for community consumption. Carbon 5 just released Raygun, Thoughtbot maintains Suspenders, there's Primo, Dr Nic's App Scrolls, and the unmaintained RailsWizard.
On paper, publishing a Rails template sounds like a great idea. Once you have one, it greatly reduces the amount of time it takes to get from zero to login. Theoretically this lets you bypass all of that boilerplate and focus on the features.
In addition, it establishes best practices and tools inside your development team. By publishing your template, it promotes those same practices and tools to the rest of the community.
How templates work
About four years ago, Rails 2.3 added the ability to create a new Rails application from a template – a ruby file containing a DSL for modifying files, installing gems, and doing other post-install housecleaning. There's a Rails Guide available for those who want to get into the nitty gritty, but hopefully I can convince you otherwise.
# rails_template.rb generate(:scaffold, "person name:string") route "root to: 'people#index'" rake("db:migrate") git :init git add: "." git commit: "-m 'Initial commit'"
Since then, people have made templates that take care of all kinds of mundane tasks. Templates have been made that configure services like Hoptoad, push everything to GitHub, and even deploy the app to Heroku.
The Cake is a Lie
While all of the reasons to use a template look like huge wins, in practice they end up being nothing more than massive time and energy sinks.
You're not Saving Time
Once you have a template ready to use, a teammate who's going to start a new project can save a lot of time.
But take a closer look, and you'll see that the time is simply being moved around. While Susan no longer spends a day configuring the testing infrastructure and getting the first story in place, Cindy spent twice that amount of time figuring out how to make it all work in a generic fashion inside the template.
Even after the first implementation, the template must be constantly tweaked and finagled to keep it up to date. Upgrading a codebase that started with a template to match the latest version is also a time consuming and difficult process.
As engineers, it's our responsibility to be aware of and constantly evaluating the latest tools and techniques. Our opinion of what's mature and what makes for a strong maintainable codebase is constantly evolving. Having a template in place solidifies "best practices" in a bad way. The technical and social friction in changing the template discourages evolution.
Discussions are Opportunities for Learning
Starting with a template stifles the learning process. While we all aim to be conscientious developers, constantly reviewing the commits to the template, and diligently picking through every file to understand what we've been given, it's not realistic.
Laziness is a virtue, and eventually, the team will just assume the template does everything the "right way." The template becomes a source of cargo-culting.
Each one of the decisions that the template makes for you should be discussions within the team. "We need a testing infrastructure - should we use rspec?" Most of the time the answer will be yes, but at some point the answer might be "No, for this project let's use mini-test." These conversations aren't just necessary to maintain a healty pace of change, but they're also a chance for the team to debate the decision and then learn from that discussion.
Scope Creep out the Gate
It's also incredibly tempting to push features that you think you use on every application into the template. User authentication is a great example. Almost every template includes Sorcery or Devise for user auth.
But there's a wide array of product-level authorization patterns out there, and before you write your first line of code is not the right time to be making that decision. Will the app need normal username/password authentication? Email addresses? Invitations? Will it just use Twitter or Facebook oauth? How about the guest-user pattern that made stripe's demo so interesting?
Inevitably, you end up removing and rearranging pieces. Congratulations! You've now started your brand new project with technical debt.
Optimizing in the Wrong Place
So if we shouldn't use a template what is a lazy developer to do? Templates optimize the initial phase of a project, but that's a rare situation for even the largest of consultancies. Instead, optimize the installation of the individual tools you use.
Gems should be as simple to use and as easy to configure as possible. They should require no configuration in the default case, and should interact cleanly with other popular gems.
Pick a gem that's hard for your team to install or configure, and improve it. Most gem authors would love contributions that make their gems easier to use, or which help the gem interact with other gems. If they refuse the contributions, then releasing a wrapper gem is another good solution.
Communication Over Codification
The fact is, "best practices" are a moving target. They evolve through team communication and cohesion. This is all part of building a professional culture, and it's how it should be. Codifying those patterns in the one tool to rule them all is misguided.
*Keep it real, we'll erase shit we don't like.* comments powered by Disqus