Double Shot #329
If by some chance you missed it, I'm now doing the edge Rails updates for the Riding Rails weblog. Oh, and I'm writing for Ruby Inside and Rails Inside now too. So, you know, I have more outlets for your important news :)
A critical look at the current state of Ruby testing - Something of a rant from Dan Croak. It's liable to provoke heated discussion.
Hoshi 0.1.0 Released...Soon - This looks like an interesting way to attack the generation and recognition of HTML from pure Ruby code. (via RubyFlow)
The RSpec Book: Behaviour Driven Development with Ruby - Looks like this one is on the way for April. No pre-order link yet though.
Live Textile JS Preview - A useful tool if you need to proofread Textile-marked up text.
SimplySearchable plugin - A new take on automatically building some useful named scopes.
A major milestone for DB2 on Rails - Those who think Rails has no place in the enterprise should note that IBM is officially supporting it with a brand-new DB2 adapter, including transactional migration support. (via Riding Rails)
Do you know when your code runs? - If you don't, you can get into trouble moving from development to production.
Legos, Play-Doh, and Programming - Coding philosophy from Jamis Buck.
7 Stages of Scaling Web Applications - Overview slides from Rackspace.
Rail's Dev Mode Performance Plugin - Josh Goebel wants to speed up your Rails in development mode.
Merb 1.0 - It's out. You can also get a ton of links from Ruby Inside.
wee_lightbox rails plugin - This actually seems to work rather well to get Lightbox integrated with Rails.
Double Shot #328
Well, I still have hours to sell, but a couple of little projects appear to be coming together, so hopefully I won't be on the bench for too long.
Scaling Ruby - The latest EnvyCast. I heard some good things about this material being presented at RubyConf.
Rubular - Ruby regular expression editor online.
Bort Update to Rails 2.2 - This prepackaged Rails solution, including various bells and whistles, is in active development.
A few reasons braid is better than 40 lines of Rake. - After wrestling with a rake-based git subtrees solution for a while, I'm getting inclined to agree that there must be a better way.
Double Shot #327
I've shut down and reformatted my Windows desktop for good (I hadn't turned it on for six months or so, it just took me this long to get around to reformatting the drives). If anyone wants a deal on a Dell PowerEdge 1800 server before I EBay it, holler.
We've stopped using rSpec ... - And ignited a bunch of debate in comments. Caboose has bailed out; the comment chain is interesting for a glimpse of what testing solutions the community is using.
Google Analytics plugin - Finally got around to making some doc and feature improvements to my fork of this project.
giternal - An alternative for managing git externals in your Rails project. Or any other project, for that matter.
Customizing to_xml and to_json in Rails
You probably already know (well, if you're a Rails developer) that you can use
To start, you can specify exactly which attributes to export with the
[sourcecode language='ruby']
@user.to_xml :only => [ :name, :phone ]
@user.to_xml :except => :password
@user.to_json :only => [ :name, :phone ]
@user.to_json :except => :password
[/sourcecode]
You can include associated records, nesting as needed, with the
[sourcecode language='ruby']
@user.to_xml :include => {:orders =>
{ :include => [:shipments, :backorders] }}
@user.to_json {:orders =>
{ :include => [:shipments, :backorders] }}
[/sourcecode]
[sourcecode language='ruby']
@user.to_xml :include => {:orders =>
{ :include => [:shipments, :backorders] },
:only => :order_date }
@user.to_json {:orders =>
{ :include => [:shipments, :backorders] },
:only => :order_date }
[/sourcecode]
You can create XML or JSON attributes from model methods by using the
[sourcecode language='ruby']
@user.to_xml :methods => :permalink
@user.to_json :methods => :permalink
[/sourcecode]
Additionally, there are some options that apply only to
to_xml
or to_json
to quickly get XML or JSON representations of Active Record model instances. But did you know that these methods are configurable? By default they simply dump all of the attributes of the model along with their values, but if you want to do something different, you can - and usually without overriding the base methods.To start, you can specify exactly which attributes to export with the
:only
or :except
options:[sourcecode language='ruby']
@user.to_xml :only => [ :name, :phone ]
@user.to_xml :except => :password
@user.to_json :only => [ :name, :phone ]
@user.to_json :except => :password
[/sourcecode]
You can include associated records, nesting as needed, with the
:include
option:[sourcecode language='ruby']
@user.to_xml :include => {:orders =>
{ :include => [:shipments, :backorders] }}
@user.to_json {:orders =>
{ :include => [:shipments, :backorders] }}
[/sourcecode]
:only
and :except
also work on includes:[sourcecode language='ruby']
@user.to_xml :include => {:orders =>
{ :include => [:shipments, :backorders] },
:only => :order_date }
@user.to_json {:orders =>
{ :include => [:shipments, :backorders] },
:only => :order_date }
[/sourcecode]
You can create XML or JSON attributes from model methods by using the
:methods
option:[sourcecode language='ruby']
@user.to_xml :methods => :permalink
@user.to_json :methods => :permalink
[/sourcecode]
Additionally, there are some options that apply only to
to_xml
. :skip_instruct
suppresses the XML processing instruction. :skip_types
suppresses the output of types to the XML. :dasherize => false
turns off dasherization of column names.
Generating Proper rdoc for cattr_accessor Declarations
If you take a look at the Rails source code, you'll find numerous useful comments like this one from ActionController::Base:
[sourcecode language='ruby']
# All requests are considered local by default, so everyone
# will be exposed to detailed debugging screens on errors.
# When the application is ready to go public, this should be set to
# false, and the protected method local_request?
# should instead be implemented in the controller to determine
# when debugging screens should be shown.
@@consider_all_requests_local = true
cattr_accessor :consider_all_requests_local
[/sourcecode]
But if you check your favorite Rails API site for documentation of
I spent some time chasing this, and it turns out to be a conflict between the way that Rails is commented and the way that rdoc thinks things should be done. There's actually a ticket in the old Rails Trac with a proposed resolution for this. As it happens, that ticket isn't quite right, but it provoked rdoc into changing things. The secret lies in the rdoc 2.x support for documenting metaprogrammed methods.
To properly document
Second, you need to change your markup comments to tell rdoc that this is a metaprogrammed method. Here's the revision for that method from ActiveController::Base:
[sourcecode language='ruby']
@@consider_all_requests_local = true
##
# :singleton-method:
# All requests are considered local by default, so everyone
# will be exposed to detailed debugging screens on errors.
# When the application is ready to go public, this should be set to
# false, and the protected method local_request?
# should instead be implemented in the controller to determine
# when debugging screens should be shown.
cattr_accessor :consider_all_requests_local
[/sourcecode]
The
The Rails Documentation team is exploring how we'll fix up the core Rails source to use the new markers. Meanwhile, you should start using this anywhere that you have the
[sourcecode language='ruby']
# All requests are considered local by default, so everyone
# will be exposed to detailed debugging screens on errors.
# When the application is ready to go public, this should be set to
# false, and the protected method local_request?
# should instead be implemented in the controller to determine
# when debugging screens should be shown.
@@consider_all_requests_local = true
cattr_accessor :consider_all_requests_local
[/sourcecode]
But if you check your favorite Rails API site for documentation of
consider_all_requests_local
, you'll come up blank. What's up?I spent some time chasing this, and it turns out to be a conflict between the way that Rails is commented and the way that rdoc thinks things should be done. There's actually a ticket in the old Rails Trac with a proposed resolution for this. As it happens, that ticket isn't quite right, but it provoked rdoc into changing things. The secret lies in the rdoc 2.x support for documenting metaprogrammed methods.
To properly document
cattr_accessor
(and similar) declarations in your own Rails code, you need to do two things. First, upgrade from your musty old rdoc 1.0.1 to a more recent version - 2.2.1 is current. If you look at their downloads you will find there is a gem version, but just installing this may not be enough: putting the gem on my system gave me rdoc 2 from the command line but rdoc 1 from rake tasks. That's because (at least on my Mac), rdoc is also out there in the ruby/1.8 standard tree, and so I had to replace the 1.0.1 there with the new bits.Second, you need to change your markup comments to tell rdoc that this is a metaprogrammed method. Here's the revision for that method from ActiveController::Base:
[sourcecode language='ruby']
@@consider_all_requests_local = true
##
# :singleton-method:
# All requests are considered local by default, so everyone
# will be exposed to detailed debugging screens on errors.
# When the application is ready to go public, this should be set to
# false, and the protected method local_request?
# should instead be implemented in the controller to determine
# when debugging screens should be shown.
cattr_accessor :consider_all_requests_local
[/sourcecode]
The
##
indicator tells rdoc that this is a metaprogrammed method, which means it will ignore the first token on the declaration and pick up the second one as the method name. The # :singleton-method#
indicator tells rdoc to document this as a class method rather than as an instance method.The Rails Documentation team is exploring how we'll fix up the core Rails source to use the new markers. Meanwhile, you should start using this anywhere that you have the
cattr
methods in your own code or plugins - and upgrade your rdoc bits in anticipation.
Double Shot #326
Yesterday saw my first posting to the official Rails weblog. A nice step on the way to world domination, I guess.
Gerrit and Repo, the Android Source Management Tools - Google has built some tools to make git work better for large-scale projects, including workflow and code-review bits.
RubyMine Public Preview - JetBrains is getting into the Rails IDE business. I may take a look, though honestly, two years after closing the IDE I don't miss it.
GitHub Code Search - A bit of poking around here reveals that Ruby coders pretty much have a lock on the chunky bacon market.
Life on the Edge with Merb, DataMapper, and RSpec - Work-in-progress aimed for folks who might be thinking of switching from Rails.
ActiveSupport::Rescuable - Pratik Naik shows how to mix this into your own code with Rails 2.2.
40 Beautiful Free Icon Sets - Some nice stuff out there; be sure to check the fine print before using.
Generating Associations in Rails 2.2
In Rails 2.2, if you include a belongs_to or references column in a call to the model generator, it will automatically add the belongs_to declaration to the model, as well as creating the foreign key column in the migration.
For example, run this from the command line:
And you'll find that the generated Order model looks like this:
[sourcecode language='ruby']
class Order < ActiveRecord::Base
belongs_to :customer
end
[/sourcecode]
Nothing earthshaking, but it will save you a few keystrokes.
Personally, I think we ought to explore the possibilities of making the model generator much more full-featured. I don't see any reason why it couldn't build validations, associations, and accessibility declarations at generation time. As a first step on this road, I've submitted a Rails patch. If you like the idea (and you've got a copy of edge hanging around), go give it a try and let me know what you think.
For example, run this from the command line:
script/generate model order order_date:datetime customer:belongs_to
And you'll find that the generated Order model looks like this:
[sourcecode language='ruby']
class Order < ActiveRecord::Base
belongs_to :customer
end
[/sourcecode]
Nothing earthshaking, but it will save you a few keystrokes.
Personally, I think we ought to explore the possibilities of making the model generator much more full-featured. I don't see any reason why it couldn't build validations, associations, and accessibility declarations at generation time. As a first step on this road, I've submitted a Rails patch. If you like the idea (and you've got a copy of edge hanging around), go give it a try and let me know what you think.
Double Shot #325
I tossed out a few more bits of open source code over the weekend: a fork of suprails (though actually I hope the original project just merges my one tiny change), and a proposed change for Rails core (which you're welcome to go test and, hopefully, +1).
When autotest fails - Apparently RSpec has a built-in server to speed up running tests. Unfortunately, I've not been able to get it working in my own projects.
The Sorry State of Blogging Software - Adam bemoans the Rails blogging infrastructure, among other choices.
Drag and Drop Sorting with JQuery and Rails - Ben Curtis shows how to do it.
Turn-Key: SaaS Rails Find Home in Morph AppSpace - Morph now offers one-click deployment for Beast, El Dorado, Substruct, and Tracks.
rboard - Rails-based forums that I need to look at the next time I have need of such a thing.
Rails Release Dates
Maybe it's just me and the amount of support and writing I'm doing these days, but I find myself fairly frequently looking at a bit of core Rails code and wondering "what that in release X"? To help figure that out, here's a list of Rails version release dates (starting with 1.0) pulled together from the svn and git repos:
7/25/04 0.5
12/13/05 1.0.0
3/22/06 1.1.0 RC1
3/28/06 1.1.0
4/06/06 1.1.1
4/09/06 1.1.2
6/28/06 1.1.3
6/30/06 1.1.4
8/09/06 1.1.5
8/10/06 1.1.6
11/23/06 1.2.0 RC1
1/05/07 1.2.0 RC2
1/18/07 1.2.0
1/18/07 1.2.1
2/06/07 1.2.2
3/14/07 1.2.3
10/05/07 1.2.4
10/12/07 1.2.5
11/24/07 1.2.6
9/30/07 2.0.0 PR (Preview Release)
11/09/07 2.0.0 RC1
11/29/07 2.0.0 RC2
12/07/07 2.0.0
12/07/07 2.0.1 (2.0 final)
12/16/07 2.0.2
5/11/08 2.0.3
9/04/08 2.0.4
10/19/08 2.0.5
5/11/08 2.1.0 RC1
5/31/08 2.1.0
9/04/08 2.1.1
10/23/08 2.1.2
10/24/08 2.2.0 (2.2 RC1)
11/14/08 2.2.1 (2.2 RC2)
11/21/08 2.2.2
2/1/09 2.3.0 (2.3 RC1)
3/5/09 2.3.1 (2.3 RC2)
3/15/09 2.3.2
3/18/09 2.3.2.1
7/15/09 2.3.3
7/18/09 2.3.3.1
9/3/09 2.3.4
11/26/09 2.3.5
2/04/10 3.0.0.beta 1 4/01/10 3.0.0.beta 2 4/13/10 3.0.0.beta 3
Filtering View Content by Role in Rails
It seems that a lot of the Rails applications I've been working on have a User model that has a many-to-many relation with a Role model, so that users can have a role like "admin" or "manager", or even multiple roles. Along with this comes the necessity to conditionally show things in views. Recently I've started moving away from having explicit @current_user.has_role("whatever") calls in the views, to some code in the application_helper.rb file:
[sourcecode language='ruby']
module ApplicationHelper
def admin_only(&block)
role_only("administrator", &block)
end
def manager_only(&block)
role_only("manager", &block)
end
private
def role_only(rolename, &block)
if not @current_user.blank? and @current_user.has_role?(rolename)
block.call
end
end
end
[/sourcecode]
Now in views I can easily mark off sections that should be displayed to only one user type:
[sourcecode language='ruby']
[/sourcecode]
It would be easy to extend the role_only method to take an array of roles and check for membership in any of them, but I haven't had need of that yet.
Hat tip to Aaron Longwell for introducing me to this technique.
[sourcecode language='ruby']
module ApplicationHelper
def admin_only(&block)
role_only("administrator", &block)
end
def manager_only(&block)
role_only("manager", &block)
end
private
def role_only(rolename, &block)
if not @current_user.blank? and @current_user.has_role?(rolename)
block.call
end
end
end
[/sourcecode]
Now in views I can easily mark off sections that should be displayed to only one user type:
[sourcecode language='ruby']
[/sourcecode]
It would be easy to extend the role_only method to take an array of roles and check for membership in any of them, but I haven't had need of that yet.
Hat tip to Aaron Longwell for introducing me to this technique.
Double Shot #324
The problem with code review jobs is that you can end up reviewing some pretty sad code.
newgem 1.0.0 all thanks to Cucumber - Dr. Nic revises his gem generation tool with lots of new features.
Double Shot #323
Looks like I've got another bit of new business spinning up. This is good, though I've still got hours free.
Announcing the textile_toolbar Plugin - A way to bring some UI goodness to textile editing. Looks useful. (via Matthew Bass)
Merb 1.0 RC3 Released! - They're apparently getting close.
App School Launch: TaskFive - An application in a week. Nice story, and potentially useful application as well.
Braid 0.5 - This tool for vendoring git and svn repos is moving along. (via RubyFlow)
I18n: An Overview - Good summary of the new 2.2 features from Ryan Bigg.
Braid 0.5 - This tool for vendoring git and svn repos is moving along. (via RubyFlow)
Review: Ruby on Rails 2.2 from Envycasts
The Rails Envy guys, Gregg Pollack and Jason Seifer, are back with another of their "Envycast" screencasts: 45 minutes about Ruby on Rails 2.2, which is scheduled to be released realsoonnow. They were kind enough to send me a review copy (which means, yes, I didn't pay for it), and here are some impressions.
You certainly get enough for your money when you purchase their "Package Deal" for $16: the screencast itself in QuickTime, iPod/iPhone, and Ogg Theora formats, a 120-page PDF ebook by Carlos Brando in English and Portuguese, and a set of code samples (you can also buy the video or the ebook separately for $9 each).
Let's take the pieces one at a time. Unlike some other screencasts, the Rails Envy guys are using green-screen technology to insert themselves in front of the slides and code samples. This adds some action to what might otherwise be a pretty dry pile of information though (fortunately, I think) the cheesy jokes are not as non-stop as in their classic "Ruby on Rails vs.
" commercials. They pack a pretty good amount of information into the screencast, touching on dozens of new features in the time they have; in some areas, they're more comprehensive than the official release notes.
The PDF is even more comprehensive than the screencast; it covers a ton of stuff out of the changelogs, with code samples and explanations (in fact, it includes the changelogs as an appendix). If you want a complete overview of the changes coming down the pike for Rails 2.2, the PDF is the single best resource I've seen so far.
The code samples parallel the ebook; they're set up as a series of tests, so you can run rake against it (this will be useful as 2.2 proceeds from RC1 to release, to see what might have changed), or dig in to test cases to see the new functionality in action.
So, is it worth the money? Well, you could get all of this information elsewhere: the Rails changelogs and source code and git repository are all public. In theory, it's easy enough to look at the git logs going back from now to the 2.1 timeframe to see everything. But as someone who's done just that (to help compile the 2.2 release notes), I can tell you it's a non-trivial exercise. There's a lot of stuff in the commit log that doesn't make immediate sense, and there are older commits that have been changed by newer ones. This set of resources does all that work for you.
But, one caution: Rails 2.2 just reached the RC1 point, and while the code is mostly locked down, it's still changing. The odds are pretty good that some part of this material will be obsolete when Rails 2.2 actually ships - and while it should be easy enough for Rails Envy to update the code and ebook, I'm not sure what they'll do if there ends up being a bug in the screencast. Hopefully they have some plan for that.
If you're considering whether to upgrade to 2.2, these resources will give you an early look at how you stand to benefit (as well as listing which 2.1 bugs have been fixed). Personally, I think the video is overkill, but I'm not all that much of a screencast fan; I can scan and even read written material much faster. But the ebook is definitely a valuable addition to the written material on Rails, and at $9, it should be a trivial amount of money for any developer to spend to get up to speed.
You certainly get enough for your money when you purchase their "Package Deal" for $16: the screencast itself in QuickTime, iPod/iPhone, and Ogg Theora formats, a 120-page PDF ebook by Carlos Brando in English and Portuguese, and a set of code samples (you can also buy the video or the ebook separately for $9 each).
Let's take the pieces one at a time. Unlike some other screencasts, the Rails Envy guys are using green-screen technology to insert themselves in front of the slides and code samples. This adds some action to what might otherwise be a pretty dry pile of information though (fortunately, I think) the cheesy jokes are not as non-stop as in their classic "Ruby on Rails vs.
" commercials. They pack a pretty good amount of information into the screencast, touching on dozens of new features in the time they have; in some areas, they're more comprehensive than the official release notes.
The PDF is even more comprehensive than the screencast; it covers a ton of stuff out of the changelogs, with code samples and explanations (in fact, it includes the changelogs as an appendix). If you want a complete overview of the changes coming down the pike for Rails 2.2, the PDF is the single best resource I've seen so far.
The code samples parallel the ebook; they're set up as a series of tests, so you can run rake against it (this will be useful as 2.2 proceeds from RC1 to release, to see what might have changed), or dig in to test cases to see the new functionality in action.
So, is it worth the money? Well, you could get all of this information elsewhere: the Rails changelogs and source code and git repository are all public. In theory, it's easy enough to look at the git logs going back from now to the 2.1 timeframe to see everything. But as someone who's done just that (to help compile the 2.2 release notes), I can tell you it's a non-trivial exercise. There's a lot of stuff in the commit log that doesn't make immediate sense, and there are older commits that have been changed by newer ones. This set of resources does all that work for you.
But, one caution: Rails 2.2 just reached the RC1 point, and while the code is mostly locked down, it's still changing. The odds are pretty good that some part of this material will be obsolete when Rails 2.2 actually ships - and while it should be easy enough for Rails Envy to update the code and ebook, I'm not sure what they'll do if there ends up being a bug in the screencast. Hopefully they have some plan for that.
If you're considering whether to upgrade to 2.2, these resources will give you an early look at how you stand to benefit (as well as listing which 2.1 bugs have been fixed). Personally, I think the video is overkill, but I'm not all that much of a screencast fan; I can scan and even read written material much faster. But the ebook is definitely a valuable addition to the written material on Rails, and at $9, it should be a trivial amount of money for any developer to spend to get up to speed.
Double Shot #322
Double Shot #321
Looks like I'm looking for another consulting project; one major one just wrapped, so I have some pretty substantial hours open going into November.
Fixtureless datas with Machinist and Sham - Another alternative for generating repeatable test data for Rails applications. I may look into this, or try to sort out the morass of competing Factory Girl branches, for my next project.
authgasm - "Rails authentication done right." The code in the readme looks nice; I haven't walked through trying to use it yet.
Scaling ActiveRecord with MySQLPlus - With Rails becoming threadsafe, people are looking at other bottlenecks.
Double Shot #320
Rails 2.2RC1 is out. Here's the official announcement. And here are the Ruby on Rails 2.2 Release Notes - of which I am rather fond, because I wrote the bulk of them.
Some other Rails 2.2 stuff:
Ruby on Rails 2.2 - The Rails Envy guys want to sell you PDF and videocast guides to the new features.
What's New in Edge Rails: Rails 2.2 Released - Summary of Features</a> and What's New in Edge Rails: Even Better Conditional GET Support - Coverage from Ryan Daigle.
And more general links:
"raise NoMethodError" raises NoMethodError. Raise it with
NoMethodError.new instead. - My first commit to the core Rails code. Hopefully not the last.
Good Homes Wanted - A batch of Rails and Ruby projects looking for new maintainers, including some fairly prominent ones.
SIPr - SIP stack written in Ruby. If only I had time to play with VOIP stuff...
REST: Some tips and implementing "Forgot your password?" - Some ideas about RESTful design.
Thinking Sphinx - New PDF from PeepCode.
GitHub Rebase #1 - Nick Quaranto is starting a new series to look at activity over on GitHub.
How to Spot a Help Vampire - Wisdom from #rubyonrails.
Some other Rails 2.2 stuff:
And more general links:
NoMethodError.new instead. - My first commit to the core Rails code. Hopefully not the last.
Contributing to Rails: Step-by-Step
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!
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:
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!
Rails 2.1.2 and 2.2RC1: Update Your RubyGems
There's a mismatch between the most recent Rails releases (2.1.2 and 2.2RC1) and older versions of RubyGems. Judging by what I've seen in various discussion fora, this is well on the way to being a FAQ. It's made more fun by the facts that
The error message doesn't implicate RubyGems
You may think you're up-to-date on RubyGems when you're not
If you're affected, you'll see this message when you try to run script/generate in a Rails application:
[sourcecode language='ruby']
undefined method empty?' for /_generator$/:Regexp
[/sourcecode]
If you see this, don't panic. It just means you need a newer RubyGems release. I'm not sure how current you need to be, but 1.1.1 is definitely too old. As I write this, 1.3.0 is current.
Now, in theory, to update to the latest version of RubyGems, you just need to run
[sourcecode language='ruby']
sudo gem update --system
[/sourcecode]
But - depending on what version of RubyGems you have installed, running that command may lie and tell you that you have nothing to update. If you're currently on RubyGems 1.1 or 1.2, you need to run a different set of commands to update RubyGems:
[sourcecode language='ruby']
sudo gem install rubygems-update
sudo update_rubygems
[/sourcecode]
You can check your current RubyGems version with
[sourcecode language='ruby']
gem -v
[/sourcecode]
If it reports 1.3.0 or later, you should be good to use the recent Rails releases.
If you're affected, you'll see this message when you try to run script/generate in a Rails application:
[sourcecode language='ruby']
undefined method empty?' for /_generator$/:Regexp
[/sourcecode]
If you see this, don't panic. It just means you need a newer RubyGems release. I'm not sure how current you need to be, but 1.1.1 is definitely too old. As I write this, 1.3.0 is current.
Now, in theory, to update to the latest version of RubyGems, you just need to run
[sourcecode language='ruby']
sudo gem update --system
[/sourcecode]
But - depending on what version of RubyGems you have installed, running that command may lie and tell you that you have nothing to update. If you're currently on RubyGems 1.1 or 1.2, you need to run a different set of commands to update RubyGems:
[sourcecode language='ruby']
sudo gem install rubygems-update
sudo update_rubygems
[/sourcecode]
You can check your current RubyGems version with
[sourcecode language='ruby']
gem -v
[/sourcecode]
If it reports 1.3.0 or later, you should be good to use the recent Rails releases.
Rails 2.2 Change: Private Methods on Association Proxies are Private
There's a small change in Active Record behavior that's going to bite some existing applications under Rails 2.2: private methods on an association proxy are actually private. To illustrate, this code would work in Rails 2.1:
user.rb:
[sourcecode language='ruby']
class User < ActiveRecord::Base
has_one :account
end
[/sourcecode]
account.rb:
[sourcecode language='ruby']
class Account < ActiveRecord::Base
belongs_to :user
private
def secret_code
"ABCDE"
end
end
[/sourcecode]
Controller code:
[sourcecode language='ruby']
@u = User.first
@code = u.account.secret_code
[/sourcecode]
With Rails 2.1, you'll actually get the secret code in @code, even though it comes from a private method of the account object. Rails 2.2 is stricter about this: that same code will fail with a NoMethodError. If you want to access a private method across an association proxy now, you'll need to use @code = u.account.send("secret_code").
Directly accessing private methods on an Active Record instance itself was already blocked in Rails 2.1, but Rails 2.2 updates that failure to give back a NoMethodError as well.
user.rb:
[sourcecode language='ruby']
class User < ActiveRecord::Base
has_one :account
end
[/sourcecode]
account.rb:
[sourcecode language='ruby']
class Account < ActiveRecord::Base
belongs_to :user
private
def secret_code
"ABCDE"
end
end
[/sourcecode]
Controller code:
[sourcecode language='ruby']
@u = User.first
@code = u.account.secret_code
[/sourcecode]
With Rails 2.1, you'll actually get the secret code in @code, even though it comes from a private method of the account object. Rails 2.2 is stricter about this: that same code will fail with a NoMethodError. If you want to access a private method across an association proxy now, you'll need to use @code = u.account.send("secret_code").
Directly accessing private methods on an Active Record instance itself was already blocked in Rails 2.1, but Rails 2.2 updates that failure to give back a NoMethodError as well.
Double Shot #319
subscribe via RSS