There are a few guides floating around about how to contribute your own code to Rails. But none of them (or at least none of the ones that I found) walk you through every step of the way. So, here's an attempt to fill that gap.

Step 0: Learn at least something about Ruby and Rails. If you don't understand the syntax of the language, common Ruby idioms, and the code that already exists in Rails, you're unlikely to be able to build a good patch (that is, one that will get accepted). You don't have to know every in-and-out of the language and the framework; some of the Rails code is fiendishly complex. But Rails is probably not appropriate as the first place that you ever write Ruby code. You should at least understand (though not necessarily memorize) The Rails Way
and The Ruby Programming Language.

Step 1: Install git. You won't be able to do anything without the Rails source code, and this is a prerequisite. The git homepage has installation instructions. If you're on OS X, use the Git for OS X installer. Everyday Git will teach you just enough about git to get by. The PeepCode screencast on git ($9) is easier to follow.

Step 2: Get the Rails source code. Don't fork the main Rails repository. Instead, you want to clone it to your own computer. Navigate to the folder where you want the source code (it will create its own /rails subdirectory) and run:

[sourcecode language='ruby']
git clone git://github.com/rails/rails.git
[/sourcecode]

Step 3: Set up and run the tests. All of the Rails tests must pass with any code you submit, otherwise you have no chance of getting code accepted. This means you need to be able to run the tests. For the tests that touch the database, this means creating the databases. With MySQL:

[sourcecode language='ruby']
mysql> create database activerecord_unittest;
mysql> create database activerecord_unittest2;
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest.*
to 'rails'@'localhost';
mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.*
to 'rails'@'localhost';
[/sourcecode]

If you're using another database, check the files under activerecord/test/connections in the Rails source code for default connection information. You can edit these files if you must on your machine to provide different credentials, but obviously you should not push any changes back to Rails.

Now if you go back to the root of the Rails source on your machine and run rake with no parameters, you should see every test in all of the Rails components pass. After that, check out the file activerecord/RUNNING_UNIT_TESTS for information on running more targeted tests.

Step 4: Fork Rails. You're not going to put your patches right into the master branch, OK? Think of a name for your new branch and run

[sourcecode language='ruby']
git checkout -b my_new_branch
[/sourcecode]

It doesn't really matter what name you use, because this branch will only exist on your local computer.

Step 5: Write your code. You're on your branch now, so you can write whatever you want (you can check to make sure you're on the right branch with git branch -a). But if you're planning to submit your change back for inclusion in Rails, keep a few things in mind:
  • Get the code right

  • Include tests that fail without your code, and pass with it

  • Update the documentation

  • Step 6: Sanity check. You know at least one other Rails developer, right? Show them what you're doing and ask for feedback. Doing this in private before you push a patch out publicly is the "smoke test" for a patch: if you can't convince one other developer of the beauty of your code, you're unlikely to convince the core team either.

    Step 7: Update your copy of Rails. It's pretty likely that other changes to core Rails have happened while you were working. Go get them:

    [sourcecode language='ruby']
    git checkout master
    git pull
    [/sourcecode]

    Now reapply your patch on top of the latest changes:

    [sourcecode language='ruby']
    git checkout my_new_branch
    git rebase master
    [/sourcecode]

    No conflicts? Tests still pass? Change still seems reasonable to you? Then move on.

    Step 8: Create your patch. Still in your branch, run

    [sourcecode language='ruby']
    git commit -a
    git format-patch master --stdout > my_new_patch.diff
    [/sourcecode]

    Sanity check the results of this operation: open the diff file in your text editor of choice and make sure that no unintended changes crept in.

    Step 9: Create a Lighthouse account. You will need one to send in a ticket with your patch. You can do this at the free signup page.

    Step 10: Create a ticket with your patch. Go to the Rails Lighthouse page. Sign in if necessary. Click on "Add New Ticket." Fill in a reasonable title and description, remember to attach your patch file, and tag the ticket with the 'patch' tag and whatever other subject area tags make sense.

    Step 11: Get some feedback. The Contributing to Rails page suggests using the rubyonrails-core mailing list or the #rails-contrib channel on IRC freenode for this. You might also try just talking to Rails developers that you know.

    Step 12: Lather, rinse, release. It's entirely possible that the feedback you get will suggest changes. Don't get discouraged: the whole point of contributing to an active open source project is to tap into community knowledge. If people are encouraging you to tweak your code, then it's worth making the tweaks and resubmitting. If the feedback is that your code doesn't belong in the core, you might still think about releasing it as a plugin.

    And then...think about your next contribution!