Happy Programming with Ruby On Rails
David Heinemeier Hansson
Introducing a Silver Bullet - a huge leap forward in productivity: Motivation.
This magical silver bullet is... motivation
"Motivation is undoubtedly the single greatest influence on how well people
perform. Most productivity studies have found that motivation has a stronger
influence on productivity than any other factor."
Steve McConnel, Rapid Development
Motivation comes from happiness
The tools we're using should optimise for happiness.
How do we make programmers happy? DHH never used to be a happy programmer - he
liked the result, not the process.
Beautiful code made him happy. Beautiful code is a way of expressing things in
code that feels right.
"Your application is not a unique snowflake" - it's not easy for people to
deal with the idea that what they aren't doing is not special. Most of the
work you do revolves around the same mundane details as everyone else. This is
the key observation behind Ruby on Rails. Optimise for the 80%; you can't
optimise for special.
Rails is about what most people do, most of the time.
First: make people believe that 80% is the same as everyone else - the 20% is
where they get to be a beautiful unique snowflake.
Convention over configuration
You normally have to do way more configuration than you want to. First do the
work, then tell one part of the system what you just did, then tell another
part as well.
Repetition usually equates to ugliness.
Code example: ActiveRecord, but with explicit code saying what the table name,
primary key, class name and foreign key are. The pattern is obvious; things
like "project" => "projects" etc.
We can turn this in to a convention where singular class names automatically
map to a plural class name - unless the programmer states othewise. Another
convention: the primary key is always called id. Another: foreign keys are
name-of-association_id.
New code example: much less code; one example of configuration where the
convention assumption didn't quite fit.
Another code example: WeblogController with show method. URL is
http://app/weblog; code is /app/views/weblog
URL is /app/weblog/show/5, runs show method with id=5.
Flexibility is overrated. You trade flexibility for readability and
productivity. It's not worth it.
Constraints are liberating. They lead to systems that are consistent, because
it's easier to follow the conventions. Now other developers can join in more
easily.
Doing the right thing. This isn't always easy. A developer has a devil and an
angel on either side. The environment determines the size of these two
creatures. In some, the devil is bigger, and says things like "You can clean
this up later; you will have more time at the end! If you know how the
algorithm works it makes you a valuable employee!"
The angel says "You should really test this; when we make a change tomorrow
the tests will tell you if you've broken something that already works. Just
follow the standards everyone else uses; you should do things consistently and
follow best practises."
DHH spent 5 years with PHP hearing that it was impossible to make beautiful
things in PHP - tried very hard to do so. Then realised it's not about if
things are possible; it's if they are encouraged. Realisation: PHP is the
devil!
The whole thing - 5,000 methods in one namespace - encourage you to be a
sloth. You can get away with this until the pressure is on - then you listen
to the devil, and end up losing the beauty.
Ruby on Rails tries to be the angel. You have to go out of your way (break the
conventions) to do something ugly. Also offers invitations to do things
better. When you create a controller or model, it automatically creates the
empty tests.
Opportunities - provide a natural space to put attributes (e.g. for
many-2-many) in the correct way.
Expectations: set up expectations that you are using best practises - not just
in the environment (encouraging tests) but in the community as well. Post code
to the mailing lists without tests and you'll be called on it.
More beauty
Account.transaction(david, mary) do
david.withdrawal(100)
mary.deposit(100)
end
If problems occur (e.g. you don't have 100!) it should roll back. Ruby makes
this stuff easy, thanks to the notion of blocks.
Rails is trying to extend ruby - creating new keywords where they feel like a
good idea. Validation is the key example here.
class Account < ActiveRecord::Base
validates_presence_of :subdomain, :name...
validates_uniqueness_of :subdomain
end
Also describing associations:
class Project < ActiveRecord::Base
belongs_to :portfolio
has_one :project_manager
has_many :milestones
has_and_belongs_to_many :categories
end
If a post has many comments, we can use post.comments to talk about just those
comments. post.comments.search should search only those comments thanks to
automatic scoping in Rails.
Extracting common usage is very important. Consider lists sorted in order.
class Story
belongs_to :iteration
acts_as_list :scope => :iteration
end
story.move_higher
story.move_lower
Another example: his crazy authorships thing. Read the slide!
Example from a controller:
session :off, :only => :feed
Turn sessions off for feeds, because feed readers will create lots of sessions
that aren't used otherwise. This code reads like parts of a spec.
HTML example - omg
tags!
Final example: XML builder for constructing RSS tags.
Finding the fit - when is Rails a good fit for you?
* Feel the hurt - if you aren't annoyed by Java/PHP and all the repetition
then you aren't ready yet
* You appreciate agile - that functional specs/big-design-up-front are evil.
Testing is good!
* You can skip the vendor - David is "not here for you". You need to be in
open source because you want to help yourself. Rails solves the problems
faced by its contributors.
One question: Does it scale? Answer: Yes.
Simon Willison - http://simon.incutio.com/