Past Articles
This article is heavily styled and is best viewed at PeepCode!

The hash rocket is dead. In Ruby 1.9, hashes whose keys are symbols can be built with a single colon.
{ key: "value", dr_nic: "The Comedian", ttl: 42}No longer will you need to remember different syntax when switching between JavaScript and Ruby (or even Python!). And youll save at least three characters every time.
Its one more reason to start using Ruby 1.9!
Please update your code accordingly.
Learn more about Ruby 1.9 at PeepCode.
Inspiration from the opening panels of The Watchmen.
Comment on this post at Hacker News.
This article is heavily styled and is best viewed at PeepCode!
Thanks for making 2010 the biggest year yet at PeepCode!
Were excited about keeping you informed and on top of your game. Weve got big plans for 2011!
This article is heavily styled and is best viewed at PeepCode!
DISCLAIMER: Reg Braithwaite delivered this quote in a completely different context1, but I think its applicable to the design of almost any software API. Illustration by Mike Rohde.
The Rails router has been written and rewritten at least four times2, including a recent rewrite for the upcoming Rails 3. The syntax is now more concise.
But never mind making it shorter! Its time for a final rewrite: Lets get rid of it altogether!
Lets get rid of the seven controller actions: index, show, new, create, edit, update and delete. Their meaning is blurred in the context of REST. Theyre an unhelpful layer between programmer and protocol.
Lets get rid of the trivial but cumbersome mental translation you have to do everytime you want to think about the HTTP GET method, the URL, the index action, and the plural_path URL helper.
Lets get rid of duplicate functionality already implemented in the controller. If you need to redirect, take action based on the user agent, or examine headers, that should be done in a controller!
And lets start thinking in URLs, resources, and APIs instead of doing image caching in models or asset bundling in view helpers. Thats the controllers job. It scales better, too.
- Routes are unnecessary configuration.
- The seven standard controller actions are legacy.
- Become intimate with your URLs dont abstract them away.
- Decrease the distance between thought and implementation.
- Let the controller do its job.
Get Back to Thinking in URLs
A big part of the problem with a routing layer is that it abstracts the developer away from the URLs that define the application. This leads to poor API designs and convoluted solutions to otherwise easy problems.
This epiphany came while writing a few Sinatra applications. The exact URL for a handler sits right in front of my eyes as I write the code for it. I cant ignore it.
As a result, I find myself spending more time thinking about how my URLs are designed. Should I be serving JSON from the same controller that serves the HTML interface, or should it be organized separately?
In contrast, you can write an entire Rails application without ever looking at a URL. The design of URLs is delegated to the framework, out of sight and out of mind.
This isnt to say that we need to lose the good parts of how Rails works with URLs. URL helper methods like pancake_path(:id) are a great idea for reducing duplication and typos. They could be implemented apart from any router.
I love URLs. I dream about them at night. I think about them before I think about anything else. Adrian Holovaty, co-creator of Django
* From Webstock 2009
Retire the Seven Action Names
It has been three years since the seven controller actions had any immediate meaning. The API no longer adds to the programmers understanding of the tasks at hand.
Experienced programmers know that inline comments mark code thats too confusing or too clever.
Yet every Rails controller is generated with two lines of repetitive comments for every action. Thats a code smell! And a failure of API design.
Every Rails developer must memorize the table at right, mapping HTTP method and URL to the controller action name. If we can get rid of the action name, the rest of the table is already self-explanatory.
So instead of going through this extra syntactical layer, lets deal directly with GET, POST, PUT, and DELETE. (Suggestions follow.)
You can tell this is a great idea because its the way unit tests already work! Lets bring this syntax back to the controller and complete the API.
# GET /pancakes# GET /pancakes.xmldef indexend# POST /pancakes# POST /pancakes.xmldef createendtest "should create pancake" do post :create assert_redirected_to pancake_path(1)endAssets Are Resources
Thinking in URLs helps you solve web-related problems in the right way.
Exhibit A: If you deploy to a site whose view fragments are already cached in memcached, its likely that Rails asset caching view helpers will not be called and CSS bundles will not be generated.
# Caching shouldn't happen herestylesheet_link_tag("a", "b", "c", :cache => true)This whole problem is easily solved by using controllers to do what they do best. Views and helpers should not generate URL-based resources.
The task of combining several CSS files into one file and caching them to disk is exactly the kind of task controllers are built to do3.

Controllers should generate and cache assets, not view helpers.
Idea 1: Sinatra
There are many ways the controller API could be improved. Existing attempts have failed to achieve wide adoption because they have tried to handle controllers, views, and models all at once4.
Instead, I think a more limited, controller-only approach could work better.
The first is already in wide use: Sinatra.
# Sinatra-style handlerget "/api/v1/report/:id" do |id| # ...endSinatra is arguably the most widely replicated Ruby web framework, having inspired implementations in Node.js, Clojure, PHP, Scala, and many other languages.
Part of the problem with writing a routing API is finding a way to describe multiple URLs in a single string. This problem is solved if you handle each URL on its own.
Theres no middle routing layer with arbitrary action names. HTTP method and URL are all you need (but handlers can filter on the user agent or other header information).
Thanks to Rack, Sinatra apps can be embedded in Rails applications. Or, Carl Lerche is writing a Rails 3 plugin that provides this syntax to Rails controllers5.
Idea 2: Method, Member, Collection
Jamis Buck introduced an implementation of REST as a plugin four years ago. Yet unlike other areas of Rails that have seen massive improvements, Rails implementation of REST is basically the same as it was in Rails 1.2.
A halfway approach could combine elements of the Rails 3 router syntax with the class method style of configuration thats already familiar to Rails developers.
# Class method and HTTP-style methods.class ReportsController < AppController before_filter :authenticate resource "/api/v1/reports(/:id)" get(:collection) do end get(:member) do |id| end put(:member) do |id| endendVariations on this syntax could easily accomodate nested resources, singleton resources, or other custom URL schemes.
Conclusion
For several years, Rails has charged forward and defined new, innovative syntaxes for writing web applications. Its time for it to happen again.
An improved syntax could get rid of stale controller actions, reduce confusion, reduce duplication, and improve the way we think about solving technical problems with web applications.
Reactions
Thanks to Reg Braithwaite and Ben Hoskings for feedback on this article.
Ben Hoskings said
I think the mere fact that a controller can be generated means that code shouldnt be there. Theres no intelligence in code that can be generated from a single resource name.
I think its doubly important because once you free the controller from having to implement the specifics of each action (like models doesnt have to implement the specifics of
#save), you have a lot more room to raise the abstraction level and start getting declarative.
I think making the controller more declarative is probably the end goal. Instead of the bulk of each action being an imperative mess, the controller can be heavier on the class-level configuration thats really proven itself in the model (associations, scopes, plugin configuration, etc.).
The provides class-level configuration directive in Merb/Rails 3 is a signal that controllers can head in this direction.
Kyle Neath gives several useful guidelines in detail for thinking about URL design.
Thoughts and reactions? Reply to @topfunky on Twitter, write a blog post of your own, or comment at Hacker News.
1 Video of Reg Braithwaite at RubyFringe. Quote is about 15:30 in.
2 The original version by David Heinemeier Hansson, then by Ulysses, then by Koz and Jamis Buck (together), and most recently by Yehuda Katz, Josh Peek, and the Rails 3 team.
3 Sample controller code. Versioning and expiration of assets are easily solved by storing a version number in the application and appending it to the link tag.
4 See hammock by Ben Hoskings, make_resourceful by Hampton Catlin and resource_controller by James Golick.
5 Carl Lerches Astaire plugin.
This article is heavily styled and is best viewed at PeepCode!

Files should be navigable by file, class, or method name and show metadata useful for distinguishing between similar files (mockup).
If I had no experience with computers and were to guess which group of people had the best software tools to do their job, I would guess computer programmers.
And if I were to guess what task would have been extensively optimized, I would guess opening files.
If you are a programmer, you know that I would be wrong.
Last summer, Dave Peck wrote about his hopes for a modern, progressive, text editor.1 Id like to focus on one missing feature thats absolutely possible today: powerful file navigation.

![]()
Keyboard
Perform any navigation task without touching the mouse.
![]()
Fuzzy Search
Find files by typing only a few letters.
![]()
Paths
Search includes folder names (relative to the project).
![]()
Metadata
File modification date and SCM status aid in file picking.
![]()
Beautiful
Terminal raster graphics dont count! I want GUI beauty.
As every Vim user knows, most of ones time spent in a text editor is spent editing, not writing (this is why Normal mode in Vim is the one you use for navigation and editing).
For most programming tasks, editing involves opening several files at once and switching between them (e.g. HTML/JavaScript/CSS).
Im talking about three tasks:
- Open any file on the computer.
- Open any file in the current project.
- Activate a file thats already open in another tab.
And yet most text editors offload these important tasks to the operating system or implement half-hearted custom solutions. Even worse, third-party plugins frequently implement file-jumping functionality for different frameworks with unique, cryptic key mappings (e.g. between implementation and test or controller and view template).
This is a core task! Editors should approach it with the same innovation and care they spend on basic text entry.

TextMate
Command-T with fuzzy search was revolutionary and was one of the main reasons I bought a copy of TextMate. But it breaks down for projects with many files of the same name (such as Ruby on Rails).

Theres no way to filter by directory.
Tabs are even worse. I frequently open more tabs than can fit on my screen, which means that both usability and the extra tabs get thrown out the window. The tab menu can only be accessed with the mouse and becomes a human-powered binary search of an unsorted list.2
Xcode
Xcodes Open Quickly command (Command-Shift-D) only works with the exact file name starting with the first letter.

Xcodes Open Quickly dialog
Many Cocoa developers store all their code files in the root directory of the project and rely on Xcodes virtual directories for organization, which is the only reason its even barely usable.
Emacs
Emacs is the closest to satisfying my requirements.
The ido-menu provides fuzzy search, including pathnames. Chris Wanstraths textmate.el plugin3 wraps it in even more useful functionality, such as autodiscovery of a project root based on the existence of a .git directory.
Open buffers (similar to tabs) can be searched for by name (C-x b) or in a list (C-x C-b).
But the inline menu is an ugly paragraph.

A powerful search hidden behind a mess of text.
The only solution I can think of, so far,
Is to smash out the windows with a crowbar. Buck 65
Once you start thinking about making file navigation better, the ideas flow freely. Could a dialog search on class or method names instead of just filenames? What about a free-form search for times and classes such as yesterday Bacon#save?
This article started with pain, developed into an idea, and ended up as an unexpected prototype implemented in MacRuby. Im using it daily and am fine-tuning the interaction, visuals, features, and performance.
The app is now available as PeepOpen with a beautiful icon. Works with TextMate, Emacs, and MacVim.
For other updates, follow @peepcode on Twitter here.

The initial prototype performs a fuzzy search on paths and lists file modification dates.
You can contribute your own froth over the design and content of this article with the Neanderthals at Hacker News.
1 Dave Peck sends supplication to the text editor gods.
2 The RubyAMP bundle for TextMate shows a simple list of open windows, but without fuzzy search.
3 Chris Wanstraths textmate.el
This article is heavily styled and is best viewed at PeepCode!
Style
Greg Storey, Airbag Industries1Before there were blogs we had websites. Beautiful, random websites that felt more like a zine one page looking nothing like the one before or after it.

Many developments in computer science have nothing to do with the capabilities of computers, but with the way we use them.
A few years ago, an article on Airbag Industries1 inspired me to think about writing a blog with a unique design per post.
There are many benefits:
- It encourages creativity both at the computer and away from it
- Its like a code kata for design
- You can easily experiment with cutting-edge CSS3 features or just learn CSS2
- Youll learn how to build a style foundation for other designs in other applications
On the downside, it takes more time than simply writing prose.
Building an art-directed blog may seem as easy as dropping an extra CSS link tag into every blog post, but a little extra work upfront makes it a lot easier.
First, I started with a layout grid in CSS. Grids have been used extensively in print design but have only recently become popular in website design. I like Tyler Tates 1kb grid2 because its the simplest thing necessary to accomplish the task.
In standard website design, elements can be placed anywhere on a page. In contrast, a grid defines boundaries in regular increments, limiting the possibilities. Instead of stifling creativity, it encourages experimentation by making it easier to think about a finite number of widths for text or images.
I use a 12 column grid (double-click anywhere on this page to see it). Twelve columns are easily divided into other increments: 12 6+6 2+5+5 4+4+4 3+3+3+3
Sinatra
The Sinatra web framework has a beautiful REST API, can be extremely powerful, and is super fast.
Its easily deployed with Phusion Passenger alongside my other Rack-based web applications.
I started with the Nesta4 blog engine and enhanced it with the additional CSS and graphic generation features I needed. All pages are cached statically with Sinatra::Cache5 for even greater speed. Although this blog could be generated with a static site generator, I find it more natural to write it in a dynamic style.
One example is the generation of text headline images with the Textorize6 renderer from Thomas Fuchs. I reference the images by URL in my CSS files. Sinatra generates the graphic on the fly when that URL is accesed (then caches it). Sinatra keeps URLs at the forefront of the web developers mind where they should be!
Other resources are generated at the view level when needed. Code snippets are formatted by the Pygments7 command-line script via a special RedCloth tag implemented as a Haml filter.

Textorize (right half) renders text edges smoothly.
No SQL
heading: About this Blogheading-font: Klavika-BoldCondensedheading-color: #000heading-background: transparentpublished: December 30 2019 at 6pmcategories: meta designsummary: An article about...format: haml.column.article %h2 Bacon :custom Haml and textile together...Its much easier to debug a visual design in development on the local machine, check the whole thing into Git, and deploy when ready. No need to write an authentication system or an article preview mechanism.
Article files are stored on disk with a bit of YAML-esque metadata at the top. Each article can be in Textile format, or can use the full power of Haml for more complicated markup.
Early on I needed to store information about the titles font size and color. Later I needed to add other custom fields for additional tagging. With an ORM this would have meant writing a migration and installing a plugin to manage tags.
There was no such problem here! I just added a few key-value pairs to the articles metadata and started using them in the application immediately.
Haml
Not only does each post get its own CSS, it can also specify its own HTML, via Haml8.
When Im designing visually in the browser, Im thinking primarily about blocks of text and images, and how they will be styled. I dont want to be thinking about HTML boilerplate or need to hunt to find a matching end tag.
Haml decreases the mental distance between HTML and CSS. I work directly with CSS selectors no matter what file I happen to be in.
But Haml isnt well suited to working with inline text. Fortunately, theres Textile9 for that!
The differences between the basic syntaxes of Textile and Markdown are negligible. Where it pulls away from Markdown is when you add new tags of your own. You can write view helpers that take a simple string and turn it into a group of HTML tags. Its not only faster to type, but I can build reusable elements for movie links, syntax-highlighted code snippets, pull quotes, and product boxes.
Textile enhancements are easily used inline within any Haml document. In RedCloth 4, the steps are:
- Write a module with methods for each of the tags you want to use (such as
movieat right). - In each method, examine the
:textkey in the options, then build and return an HTML string. I build links for themovandm4vversions of each movie. - Write a Haml filter. The name of your module will be used as the name of the filter.
- Extend RedCloth with your custom module.
- Add more methods to your tags module as needed.
The code samples at right were built this way. I specify a path to a source file and it runs it through pygmentize. It also prepends a link to the source file itself.
The end result is a text system customized for writing about code, but it looks great, too! I cant imagine using a CMS that was any less powerful than this.
.column.article %h2 Custom Filter Sample :custom_red_cloth movie. http://example.com/movie.mov source. /tutorials/code.rb buy. http://peepcode.com/productsmodule CustomTags def movie(opts) my_text = opts[:text] # Build an HTML string around my_text # ... return my_text end endmodule Haml module Filters # Renders custom textile. module CustomRedCloth include ::Haml::Filters::Base lazy_require 'custom_tags' def render(text) red_cloth = ::RedCloth.new(text) red_cloth.hard_breaks = false red_cloth.extend CustomTags red_cloth.to_html end end endendSASS/CSS
@import ../page_util@import ../pygments_pastie+masthead-reset+dark-logo+dark-masthead-menu!base_color = #d1e3ff.prose +grid_6 float: left margin: left = !grid_gutter_width top = !line_height*5
Archives page with screenshots
In a recent copy of Print Magazine11, someone talked about designing a style sheet for the magazine back in the 70s. For some reason, the extra space jolted my brain into thinking differently. Style. Sheet.
A stylesheet isnt supposed to be a receptacle into which one tosses a bunch of unrelated visual directives. Its a coherent guideline for how things should look. It should be planned and reusable. And like backend code, it may take several iterations of use in the real world to get it right.
SASS is a huge part of achieving that concept in this blog.
People get emotional when they hear about SASS. Either they see it as a threat to traditional CSS (used only by hacks who havent taken the time to learn it) or they welcome it as the best thing to happen to the Internet.
After working with this blog for a few months, Im in the second camp.
As an example, any page can be designed with a light or a dark background. A few mixins at the top automatically adjust the page background, logo color (implemented as an image sprite), and menu colors. All these are contained in the stylesheet and dont require any modification of the pages HTML.
The technical parts of the grid and vertical rhythm are also wired into my SASS stylesheets. I can give elements meaningful names in HTML, then specify +grid_6 in SASS to make the element six columns wide (alternately, I could have used arguments like grid(6)).
Variables like grid_gutter_width and line_height are available to the whole application. I rarely type a number; instead I use meaningful variables to add margins or manipulate elements into position.
And if Im going to spend that much time in the powder room, I want to show it off. The archives page uses webkit2png.py10 to take a screenshot of each page and display it in a grid.
JavaScript
A unique design for each post is great, but how about unique JavaScript for each post?
For my Rails 3 upgrade screencast, I wanted to show a timeline of Rails release dates. Ive recently become enamored with RaphaelJS12 and it took only a few lines of code to import a JavaScript file for posts that want one.
I wrote a custom Timeline function that plots dates as large dots.
Conclusion
As with many features of this blog, it will take a while to figure out how to use them all fully. In the meantime, its a great learning experience and a fun output for creativity.
I havent published the source yet and may never. But now you have the ideasimplement them on your own blog!

In an earlier post, RaphaelJS was used to chart Rails release dates.
jQuery(function () { var paper = Raphael("graph", 940, 81), timeline; timeline = new Timeline(paper, [ {date:"06/25/2004", version:"0.5"}, {date:"12/13/2005", version:"1.0.0"}, {date:"12/07/2007", version:"2.0.0"}, {date:"6/10/2010", version:"3.0 ?"} ]);});1 Airbag Industries wrote on the old days when blogs were designed like zines.
2 The 1kb grid is the simplest thing necessary to get the job done. I convert it to SASS with the included css2sass command.
3 With a hack to ruby-mode in Emacs, I can easily jump to any Sinatra URL handler in a file.
4 Nesta is a minimal blog engine by Graham Ashton (but easy to extend). Its built on the Sinatra web framework.
5 Sinatra::Cache source code
7 Pygments is the best syntax highlighter out there. When you view diffs and code at GitHub, youre viewing pygments. Pipe code to it on the command line.
8 The Haml template engine is available for Ruby and other languages.
9 Textile is a syntax for formatting prose.
10 webkit2png.py is a capable screenshot capturing script for Mac OS X. Theres a Ruby port, but the original works well enough that I dont see the need. Ive wrapped it in the osxscreenshot gem.
11 Print Magazine is a classic (over 70 years in publication). Baseline Magazine is a more academic European counterpart. I recently bought a subscription to both.
12 RaphaelJS is a JavaScript-based SVG drawing library.
13 The Plainview web browser is a full-screen browser, useful not only for HTML-based presentations.
Aaron Patterson showed us some tenderlove this week by releasing Rails 3.0.5. Have a peek at what got updated.
Bugs Fixed
- Fix when gzip returns a UTF-8 string on Ruby 1.9, when it is actually binary. commit
- Active Record limit values will not escape Arel SQL Literal nodes. commit
- Relation#where calls will always produce AND statements regardless of how conditions hashes behaves (reverting 00693209ecc).
- Observer callbacks will only be executed once when using STI classes in ActiveRecord. commit
Deprecations Added:
- Deprecate Relation#& alias for Relation#merge. commit
- Deprecated support for interpolated association conditions with the :conditions => foo = #{bar} syntax, and added the new interpolation syntax which is :conditions => proc { foo = #{bar} }. commit
This is not a complete list of changes. The complete list of changes can be found here
SHA1 Checksums:
- actionmailer-3.0.5.gem b25750c8126aa21db27d7b0ee829b2e94e525ebc
- actionpack-3.0.5.gem 0a6f7f9ac2960ff224c913877a2917e1bea80df3
- activemodel-3.0.5.gem 1556900a7afa1cdcdf4641edbcdd2c24f98bb2de
- activerecord-3.0.5.gem 33dd05d7362931564f6f15ea7130cc27a5fc09e8
- activeresource-3.0.5.gem 758f893cbb7ef945c857bf4ca044b94017bdc437
- activesupport-3.0.5.gem 195fa3f7fa044134703a655cdb906edb515286c4
- rails-3.0.5.gem 32322bf9952d76c5fa0054c8533c0c58609f40aa
- railties-3.0.5.gem 3dddf14736dec991c3dbbe2d89495613e72c19c7
There is a vulnerability in Ruby on Rails which could allow an attacker to circumvent the CSRF protection provided. This vulnerability has been assigned the CVE Identifier CVE-2011-0447.
- Versions Affected: 2.1.0 and above
- Not affected: Applications which dont use the built in CSRF protection.
- Fixed Versions: 3.0.4, 2.3.11
Impact
Certain combinations of browser plugins and HTTP redirects can be used to trick the users browser into making cross-domain requests which include arbitrary HTTP headers specified by the attacker. An attacker can utilise this to spoof ajax and API requests and bypass the built in CSRF protection and successfully attack an application. All users running an affected release should upgrade or apply the patches immediately.
Releases
The 3.0.4 and 2.3.11 releases are available at the normal locations.
Upgrade Process
There are two major changes in this fix, the behaviour when CSRF protection fails has changed and the token will now be required for all non-GET requests.
After applying this patch failed CSRF requests will no longer generate HTTP 500 errors, instead the session will be reset. Users can override this behaviour by overriding handle_unverified_request in their own controllers.
Users must still take care that users cannot be auto logged in via non-session data. For example, an application using filters to implement remember me functionality must either remove those cookies in their handle_unverified_request handlers or ensure that the remember me code is only executed on GET requests. A custom handler which removes the remember_me cookie would look like:
def handle_unverified_request super # call the default behaviour which resets the session cookies.delete(:remember_me) # remove the auto login cookie so the fraudulent request is rejected.endThere are two steps to ensuring that your application sends the CSRF Token with every ajax request. Providing the token in a meta tag, then ensuring your javascript reads those values and provides them with each request. The first step involves you including the csrf_meta_tag helper somewhere in your applications layout. Rails 3 applications likely already include this helper, however it has now been backported to the 2.3.x series. An example of its use would be something like this in application.html.erb:
<%= javascript_include_tag :defaults %><%= csrf_meta_tag %>In addition to altering the templates, an applications javascript must be changed to send the token with Ajax requests. Rails 3 applications can just update their rails.js file using rake rails:update, 2.x applications which dont use the built-in ajax view helpers will need to add a framework-specific snippet to their application.js. Examples of those snippets are available:
- prototype-snippet.js Prototype script which includes the csrf token in every Ajax request
- jquery-snippet.js JQuery script which includes the csrf token in every Ajax request.
Workarounds
There are no feasible workarounds for this vulnerability.
Patches
To aid users who arent able to upgrade immediately we have provided patches for the two supported release series. They are in git-am format, 3-0-csrf.patch includes two changesets, the others consist of a single changeset.
- 2-3-csrf.patch Patch for 2.3 series
- 3-0-csrf.patch Patch for 3.0 series
Given the severity of the problem we are also providing backported fixes to the 2.2 and 2.1 series. There will be no gem releases for these versions but the stable branches in git will be updated.
- 2-2-csrf.patch Patch for 2.2 series
- 2-1-csrf.patch Patch for 2.1 series
Please note that only the 2.3.x and 3.0.x series are supported at present. Users of earlier unsupported releases are advised to upgrade as soon as possible as we cannot guarantee continued security fixes indefinitely.
Credits
Thanks to Felix Grbert of the Google Security Team for reporting the vulnerability to us and working with us to ensure that the fix didnt introduce any new issues. Thanks also to the Shopify development team for their assistance in verifying the fix and the upgrade process. The original vulnerability has been reported to vendors by kuza55
There is a vulnerability in Ruby on Rails which could allow an attacker to circumvent the CSRF protection provided. This vulnerability has been assigned the CVE Identifier CVE-2011-0447.
- Versions Affected: 2.1.0 and above
- Not affected: Applications which dont use the built in CSRF protection.
- Fixed Versions: 3.0.4, 2.3.11
Impact
Certain combinations of browser plugins and HTTP redirects can be used to trick the users browser into making cross-domain requests which include arbitrary HTTP headers specified by the attacker. An attacker can utilise this to spoof ajax and API requests and bypass the built in CSRF protection and successfully attack an application. All users running an affected release should upgrade or apply the patches immediately.
Releases
The 3.0.4 and 2.3.11 releases are available at the normal locations.
Upgrade Process
There are two major changes in this fix, the behaviour when CSRF protection fails has changed and the token will now be required for all non-GET requests.
After applying this patch failed CSRF requests will no longer generate HTTP 500 errors, instead the session will be reset. Users can override this behaviour by overriding handle_unverified_request in their own controllers.
Users must still take care that users cannot be auto logged in via non-session data. For example, an application using filters to implement remember me functionality must either remove those cookies in their handle_unverified_request handlers or ensure that the remember me code is only executed on GET requests. A custom handler which removes the remember_me cookie would look like:
def handle_unverified_request super # call the default behaviour which resets the session cookies.delete(:remember_me) # remove the auto login cookie so the fraudulent request is rejected.endThere are two steps to ensuring that your application sends the CSRF Token with every ajax request. Providing the token in a meta tag, then ensuring your javascript reads those values and provides them with each request. The first step involves you including the csrf_meta_tag helper somewhere in your applications layout. Rails 3 applications likely already include this helper, however it has now been backported to the 2.3.x series. An example of its use would be something like this in application.html.erb:
<%= javascript_include_tag :defaults %><%= csrf_meta_tag %>In addition to altering the templates, an applications javascript must be changed to send the token with Ajax requests. Rails 3 applications can just update their rails.js file using rake rails:update, 2.x applications which dont use the built-in ajax view helpers will need to add a framework-specific snippet to their application.js. Examples of those snippets are available:
- prototype-snippet.js Prototype script which includes the csrf token in every Ajax request
- jquery-snippet.js JQuery script which includes the csrf token in every Ajax request.
Workarounds
There are no feasible workarounds for this vulnerability.
Patches
To aid users who arent able to upgrade immediately we have provided patches for the two supported release series. They are in git-am format, 3-0-csrf.patch includes two changesets, the others consist of a single changeset.
- 2-3-csrf.patch Patch for 2.3 series
- 3-0-csrf.patch Patch for 3.0 series
Given the severity of the problem we are also providing backported fixes to the 2.2 and 2.1 series. There will be no gem releases for these versions but the stable branches in git will be updated.
- 2-2-csrf.patch Patch for 2.2 series
- 2-1-csrf.patch Patch for 2.1 series
Please note that only the 2.3.x and 3.0.x series are supported at present. Users of earlier unsupported releases are advised to upgrade as soon as possible as we cannot guarantee continued security fixes indefinitely.
Credits
Thanks to Felix Grbert of the Google Security Team for reporting the vulnerability to us and working with us to ensure that the fix didnt introduce any new issues. Thanks also to the Shopify development team for their assistance in verifying the fix and the upgrade process. The original vulnerability has been reported to vendors by kuza55
Two new versions of Ruby On Rails have been released today. As well as including a number of bugfixes they contain fixes for some security issues. The full details of each of the vulnerabilities are available on the rubyonrails-security mailing list. We strongly urge you to update production Rails applications as soon as possible. Rather than post the advisories individually to this blog, Ill just link to the google talk archives.
Install the latest version using gem install rails. Or if youre using bundler, edit your gemfile and run bundle update rails.
Summaries
Affecting 2.x.x and 3.0.x
- XSS Risk in mail_to :encode=>:javascript CVE-2011-0446
- CSRF Bypass Risk CVE-2011-0447
Affecting 3.0.x only
- Filter Problems on Case Insensitive Filesystems CVE-2011-0449
- Potential SQL Injection with limit() CVE-2011-0448
Two new versions of Ruby On Rails have been released today. As well as including a number of bugfixes they contain fixes for some security issues. The full details of each of the vulnerabilities are available on the rubyonrails-security mailing list. We strongly urge you to update production Rails applications as soon as possible. Rather than post the advisories individually to this blog, Ill just link to the google talk archives.
Install the latest version using gem install rails. Or if youre using bundler, edit your gemfile and run bundle update rails.
Summaries
Affecting 2.x.x and 3.0.x
- XSS Risk in mail_to :encode=>:javascript CVE-2011-0446
- CSRF Bypass Risk CVE-2011-0447
Affecting 3.0.x only
- Filter Problems on Case Insensitive Filesystems CVE-2011-0449
- Potential SQL Injection with limit() CVE-2011-0448
It's been a killer month for new Ruby and Rails jobs over at the Ruby Inside Jobs board so I'm going to cut the filler to a minimum today.. though if you want to learn more about posting one of your own, check our Post A Job page. The current bonus is you'll get your job ad into the 4000+ subscriber-strong Ruby Weekly for free!
There are a couple of really appealing jobs in here (particularly the first one) and they span the US with a few in the United Kingdom and one in Australia for good measure:
Innovation Developer - San Francisco, California
salesforce.com, inc. is looking for a Innovation Developer - the sort of developer who reads HN and TechCrunch, who's played with tools like Raphael and CoffeeScript, and who wants to work on interesting prototypes with the latest tools. This sounds like a great position! It's in downtown SF and you can even get a $100/mo fitness reimbursement click here to learn more.
Great Ruby Developer Needed - London, UK
Econsultancy is an award-winning online publisher based in London and New York. They're looking for a developer to work at their London office with general experience of Ruby, Rails and Unix/Linux - salary is up to 60k click here to learn more.
Ruby on Rails Developer - Pasadena, California
Goldstar is a ticket and entertainment company looking for a full-time Rails developer to join a geographically-dispersed, test-happy, and pair-friendly team of developers building services for 1.2 million members across the US. This job does not demand you be based near Pasadena, CA (though that's ideal) but at least one visit per year to HQ is required click here to learn more.
Ruby/Rails Engineers - Edinburgh & Cambridge, UK
FreeAgent is a fast growing and hugely popular UK based startup obsessed with building fantastic online accounting software. They're a small team of smart people looking to hire productive Ruby and Rails developers in Edinburgh or Cambridge. You'll be working on adding and maintaining features for our existing applications and making sure their software scales up click here to learn more.
Ruby on Rails Developer - Boston, Massachusetts
The District Management Council is looking for an experienced Web developer with 2+ years of Rails and JavaScript experience plus MySQL, HTML, and CSS proficiency to work on their Web applications helping to dramatically improve public education in America today click here to learn more.
Ruby/Java Web Developers - Arlington, Virginia
Healthcentral is an online health information site looking for, ideally, a developer experienced with both Java and Ruby related technologies. A BS/MS in Computer Science is preferred, along with 2-4 years of industry experience preferably in startup environments click here to learn more.
Ruby Developer - Palo Alto, California
Wildfire Interactive is a rapidly expanding, VC-funded tech startup in the social media marketing space. They're using Rails and Sinatra and building many 'pure Ruby' components so they want Ruby developers with full-stack experience. Oh, and testing is a must click here to learn more.
Ruby Developer - Lewisville, Texas
Geoforce Inc provides asset visibility to the oil and gas industry through wireless devices feeding data to a Rails-powered SaaS app. They want a developer with 3 years of Rails experience, as well as Postgresql, HTML, and JavaScript experience generally click here to learn more.
Graduate Rails Developer - London, UK
AlphaSights are looking for a Computer Science graduate (or equivalent) with a passion for Ruby and Rails to work in a small team at their Covent Garden offices. No commercial Rails experience is necessary and a highly competitive salary is offered click here to learn more.
Rails Developer - Cleveland, Ohio
Within3 is a professional networking site for the top institutions and physicians in the healthcare industry looking for a Rails developer. At least 3-5 years of Ruby experience is needed as well as thorough knowledge of front-end technologies (XHTML, CSS, JavaScript) click here to learn more.
Senior Ruby (Rails/Sinatra) Developer - Santa Monica, California
TRUECar, Inc. is looking for a Ruby developer with Sinatra experience to work on improving their car price research service. Your TDD and Agile-fu needs to be strong. A highly competitive salary, 100% medical, and equity are offered click here to learn more.
Sr. Ruby Developer - Coronado, California
StockTwits wants a senior-level Ruby developer with Ruby, Rails (with HAML), TDD and HTML5 experience. A Bachelor's degree or better in Computer Science or a related technical discipline is required click here to learn more.
Ruby on Rails Developer - Chicago, Illinois
Obtiva is looking for developers for its Chicago and Denver locations - no 'rock stars' or 'ninjas' but passionate, friendly team players with Ruby, Rails, and Agile experience click here to learn more.
Web Developer - San Francisco, California
Do you have a passion for design as well as code? Hybrid Design wants you! They're working for clients like Apple, Nike, and TED and need a full-time Web developer with both Ruby and design chops click here to learn more.
Ruby Developer - Evanston, Illinois
Celect builds member-management systems for organizations like churches and fraternities. They need a full-time Ruby developer for their engineering team who has experience with RSpec, Passenger, and PostgreSQL. The job is on-site in Evanston, IL click here to learn more.
Ruby on Rails Software Engineer - Sterling, Virginia
Grab Networks is looking for analytical individuals with strong computational skills to work on multiple levels of a complex technology stack. You'll need 5-6 years' experience developing dynamic, data-driven, commercial web applications click here to learn more.
Ruby/JRuby Tools Engineer - San Mateo, California
Where can you work on challenging engineering problems while saving the planet? At eMeter! eMeter is seeking an Java/Ruby/JRuby Automation/Tools Engineer to drive the development of automation tools click here to learn more.
Ruby Developer - Melbourne, Australia
TrikeApps is looking for a Ruby Developer to work in their Melbourne, Australia office. Assistance with relocation and visa sponsorship is available for the right candidate wanting to move to Australia. Two years of experience developing webapps is required click here to learn more.
Ruby on Rails Software Engineer - San Francisco, California
AKQA (one of the world's most influential creative and technology companies) is looking for a Ruby on Rails Software Engineer with 3 years' experience of Rails and familiarity with Unix/Linux click here to learn more.
Eloquent Ruby (Amazon.com - print & Kindle) by Russ Olsen is the first Ruby book I've read in its entirety within 24 hours; it's that good. That may be all you need to know before you buy a copy at Amazon.com, Amazon.co.uk or read it on Safari (if you have an account). If you want to learn more though, keep reading.
What Is "Eloquent Ruby"?
Eloquent Ruby is a book published by Addison Wesley and written by Russ Olsen (who also wrote Design Patterns in Ruby a few years ago). It clocks in at around 400 pages and has 31 chapters clocking in at around a punchy 10 pages each. Each chapter is titled as a guideline you should follow to write "eloquent" Ruby - things like Create Classes That Understand Equality and Write Code That Looks Like Ruby - and typically the claim is explained, some code examples shown and discussed, some real world examples pointed to, and that's it.
As with Design Patterns in Ruby, Russ adopts a chatty, familiar tone. Reading this book is like reading a book specifically written for you by a friend. He doesn't shoot off on many unnecessary tangents and he keeps the stories short and sweet but this book certainly couldn't be called dry.
The book is also notably short of egregious errors or omissions. Even when I don't read something with a fine-toothed comb on standby, I can usually pick out a laundry list of factual and grammatical errors or omissions (as both Obie Fernandez and my wife will attest) but Eloquent Ruby gave me little to chew on. I can only bring to mind a few spacing and formatting issues and only one true "error": a > instead of a < in a class definition on a single example.
Russ tries to remain neutral with his choice of Ruby implementations but the book seems to focus primarily on Ruby 1.9 (Ruby 1.9.1 specifically but that's just due to when he wrote it) while providing useful footnotes in the cases where there are differences to Ruby 1.8. No matter what Ruby implementation you're using, there's little to confuse you as most of it is very non-implementation and non-version specific.
I wholeheartedly recommend this book to anyone except those who, well, could have written a similar book themselves. The short punchy chapters make it a delight to read and gives the option of reading it merely 10 minutes at a time before bed or similar. The short chapters also make it useful as a reference if you forget how to do a certain thing like, say, use method_missing, even though it's not put together as a reference book at all. Lastly, this book is a must read if you're not confident with Ruby idioms and the best way to structure and lay out your code - Russ's approaches reinforce the current "standard" way to write Ruby and this alone is worth the price of admission.
Who Should Buy It?
- Any Ruby developer who doesn't yet feel like they're at guru level (that's most of us!)
- Anyone who wants to get a feel for the typically undocumented style, syntax, and structural standards of top Ruby developers.
Who Shouldn't Buy It?
- Anyone without a sense of humor or who doesn't like a chatty, familiar type of writing.
- Matz, Dave Thomas, Chad Fowler, Russ Olsen himself, and a few others.
- Anyone who's resistant to change and wants to keep coding Ruby "their way."
The Chapters
The chapter titles in Eloquent Ruby are useful enough to give you an indication of the level(s) it aims at and whether it would be interesting to you, so here goes:
- Write Code That Looks Like Ruby
- Choose The Right Control Structure
- Take Advantage Of Ruby's Smart Collections
- Take Advantage Of Ruby's Smart Strings
- Find The Right String With Regular Expressions
- Use Symbols To Stand For Something
- Treat Everything Like An Object - Because It Is
- Embrace Dynamic Typing
- Write Specs!
- Construct Your Classes From Short, Focused Methods
- Define Operators Respectfully
- Create Classes That Understand Equality
- Get The Behavior You Need With Singleton And Class Methods
- Use Class Instance Variables
- Use Modules As Name spaces
- Use Modules As Mixins
- Use Blocks To Iterate
- Execute Around With A Block
- Save Blocks To Execute Later
- Use Hooks To Keep Your Program Informed
- Use method_missing For Flexible Error Handling
- Use method_missing For Delegation
- Use method_missing To Build Flexible APIs
- Update Existing Classes With Monkey Patching
- Create Self Modifying Classes
- Create Classes That Modify Their Subclasses
- Invent Internal DSLs
- Build External DSLs For Flexible Syntax
- Package Your Programs As Gems
- Know Your Ruby Implementation
- Keep An Open Mind To Go With Those Open Classes
There's something for everyone and it gets progressively more advanced.
How to Get Eloquent Ruby
If you want a print or Kindle copy, head to Amazon.com, Amazon.co.uk, or your other favorite book retailer. If a PDF or EPUB file is more to your taste, InformIT has those for sale (currently for $28.79).
Kindle Preview
Yes, I'm sad enough to have had this in my calendar for some time but.. it's Ruby's 18th "birthday" today! Happy Birthday Ruby! While this means she can drink, vote, and otherwise join her slightly older friends Perl (24) and Python (21) in the nightclubs of Europe, I was surprised to learn that coming of age in Japan is at 20 years old.
From Wikipedia's Ruby entry:
The name "Ruby" was decided on during an online chat session between Matsumoto and Keiju Ishitsuka on February 24, 1993, before any code had been written for the language. Initially two names were proposed: "Coral" and "Ruby", with the latter being chosen by Matsumoto in a later email to Ishitsuka. Matsumoto has later stated that a factor in choosing the name "Ruby" was because it was the birthstone of one of his colleagues.
Wikipedia
If you're interested in learning more, this interview with Matz back in 2001 will give you more history and background to the creation of Ruby.
While Matz has said that February 24, 1993 is Ruby's "birthday" (back when I Will Always Love You by Whitney Houston was topping the charts), the first public release wasn't until December 21, 1995 when Ruby 0.95 was released and the first mailing list established. Ruby 1.0 followed a year later on December 25, 1996, establishing the tradition of Christmas Day Ruby releases.
Here's to 18 more, love.
P.S. Before I get any grief for putting a picture of a young woman on this post it's happened before *sigh* this actress played a character called Ruby in the UK's most popular soap opera and was about 18 at the time. Rock and roll.
Rails 3 is great. RSpec 2 is great. And Ruby 1.9.2 is really great. Getting them all running together and quickly, however, isn't entirely straightforward. In this post I demonstrate how to get everything ticking over along with automatically running, super-snappy test runs.
The ultimate outcome is using Ruby 1.9.2 (though much of this is relevant to 1.8 still) to create a Rails 3 app, hook up RSpec 2, and be able to run specs quickly. The first two parts are easy(ish) but the "quickly" part requires some tinkering. Grab a coffee and carry on..
Create a new Rails 3 app
Got Rails 3 installed? If not, gem install rails will see you good. Then head on down to your favorite project folder with your shell and create a new Rails 3 app like so:
rails new myapp --skip-test-unit
You can retroactively bring RSpec 2 into an existing Rails 3 project, of course, but it's easier for this walkthrough to start afresh in case of application-specific issues.
Hooking up RSpec 2 with RSpec-Rails
Edit the Gemfile file in your new Rails project (myapp/Gemfile in this example) and add the following block to the bottom:
group :development, :test do gem 'rspec-rails'endThis tells Bundler (a gem management and dependency tool Rails 3 likes to lean on) we want to use the rspec-rails gem which will get RSpec running with Rails 3.0 for us. Next, we get Bundler to do its thing:
bundle
This will install all of the gems referenced in Gemfile, including rspec-rails. (You can use bundle install instead, if you prefer, but bundle on its own works too.)
Last but not least, we need to run RSpec's 'generator' that rspec-rails has put in place for us:
rails generate rspec:install
The generator creates a few files. Namely:
.rspec- a config file where we can store extra command line options for therspeccommand line tool. By default it contains--colourwhich turns on colored output from RSpec.spec- a directory that will store all of the various model, controller, view, acceptance and other specs for your appspec/spec_helper.rb- a file that's loaded by every spec (not in any automatic way but most haverequire 'spec_helper'at the top). It sets the test environment, contains app level RSpec configuration items, loads support files, and more.
We still can't run rake and see anything interesting yet because we don't have a database or any models initialized.
Creating a model to test
Let's take the easy way out and use the scaffold generator to flesh out something for us to test (as well as to see what spec files can be generated automatically):
rails generate scaffold Person name:string age:integer zipcode:string
It's worth noting that when you generate the scaffold numerous spec files are also created (thanks to rspec-rails):
spec/models/person_spec.rbspec/controllers/people_controller_spec.rbspec/views/people/edit.html.erb_spec.rbspec/views/people/index.html.erb_spec.rbspec/views/people/new.html.erb_spec.rbspec/views/people/show.html.erb_spec.rbspec/helpers/people_helper_spec.rbspec/routing/people_routing_spec.rbspec/requests/people_spec.rb
Now bring the database up to speed with the migration for the new model:
rake db:migrate
Now let's run rake - finally! The result:
...............**............Pending: PeopleHelper add some examples to (or delete) /Users/peter/dev/rails/myapp/spec/helpers/people_helper_spec.rb # Not Yet Implemented # ./spec/helpers/people_helper_spec.rb:14 Person add some examples to (or delete) /Users/peter/dev/rails/myapp/spec/models/person_spec.rb # Not Yet Implemented # ./spec/models/person_spec.rb:4Finished in 0.31043 seconds29 examples, 0 failures, 2 pending
Rock and roll. We're up and running. Sort of. Let's put in some "real" specs to be sure things are working nicely.
Change spec/models/person_spec.rb to the following rather contrived pair of specs:
require 'spec_helper'describe Person do it "can be instantiated" do Person.new.should be_an_instance_of(Person) end it "can be saved successfully" do Person.create.should be_persisted endendNot the most useful things to spec out, admittedly, but you get a little database action and get rid of a pending spec we had cluttering things up. We haven't got anything else we can seriously test yet anyway.
Now let's run rake spec:models to focus our efforts on what we've just done:
..Finished in 0.09378 seconds2 examples, 0 failures
How to have specs run automatically with Watchr
Let's assume we've progressed with developing our app and we're working on models and controllers, testing along the way. Rather than running rake or bundle exec rspec all of the time, wouldn't it be great to have the relevant spec run automatically when we either edit the spec or a model/controller that has a spec? Well, with watchr, we can. (Note: Some people prefer autotest. I find watchr more flexible and useful for other things beyond just running specs.)
But if you really want to use autotest, Mike Bethany explains how to set it up in a similar scenario in a post of his own, along with autotest-growl for OS X notifications.
Add watchr to your Gemfile's testing and production gem section:
group :development, :test do gem 'rspec-rails' gem 'watchr'endThen run bundle to install it.
Next, create a file called .watchr in your app's root folder and populate it with this code:
def run_spec(file) unless File.exist?(file) puts "#{file} does not exist" return end puts "Running #{file}" system "bundle exec rspec #{file}" putsendwatch("spec/.*/*_spec\.rb") do |match| run_spec match[0]endwatch("app/(.*/.*)\.rb") do |match| run_spec %{spec/#{match[1]}_spec.rb}endThis 'watchr script' directs a running watchr process to do a few things:
- If any file ending in
_spec.rbunder thespec/directory changes, run therun_specmethod with its filename. - If any
.rbfile under theapp/directory changes, call therun_specmethod with an equivalently named_spec.rbfile underspec. run_fileaccepts a filename for a spec file, checks it exists, and tells the system to run it (usingsystem)
If you now run watchr .watchr to use the .watchr script, not much will happen. But if you make any change (or even just re-save) to, say, spec/models/person_spec.rb, that spec will run automatically. Make a change to app/models/person.rb and it's the same deal. To stop watchr, CTRL+C saves the day.
Watchr can be used for a lot more than this but this is just for starters ;-)
Optionally, you might also like to create lib/tasks/watchr.rake and include the following code so you can just remember to run rake watchr instead (it's nice to have anything you run within a project contained in one place):
desc "Run watchr"task :watchr do sh %{bundle exec watchr .watchr}endHow to get faster spec runs with Spork
We've got Rails 3 running with RSpec 2 and watchr's giving us some automatically-running-spec love. But do you notice how slow it is? Specs run quickly once they're loaded but there are several seconds of waiting beforehand.
If you run time rake spec:models with Ruby 1.9.2, you'll probably see a wallclock time of over 5 seconds (5.204s on my machine and I'm SSDed up) - holy splingledoops! If not, you're lucky, but it's a commonly reported problem with some improvements expected in Ruby 1.9.3. We can't wait that long though..
Enter Spork. Spork is a tool that loads the Rails environment and then forks each time you want to run some specs (or tests, it can be set up to run with Test::Unit too). In this way, the whole Rails initialization process is skipped, shaving valuable seconds off of your spec runs.
Edit your Gemfile again and include Spork:
gem 'spork', '~> 0.9.0.rc'
Run bundle to install Spork.
Next, Spork needs to make some changes to your spec/spec_helper.rb file. Because it only initializes the Rails environment once and then forks it, you might have initialization features that you need to run on each test run. Spork will let you do this but it needs to make those changes first. Run:
spork --bootstrap
The result:
Using RSpecBootstrapping /Users/peter/dev/rails/myapp/spec/spec_helper.rb.Done. Edit /Users/peter/dev/rails/myapp/spec/spec_helper.rb now with your favorite text editor and follow the instructions.
Bring up spec/spec_helper.rb. All spork --bootstrap has done is add some extra code to the top of the file. Read the comments there to get a better feel for what to do and what Spork requires and keep them in mind as we progress (in case you want to do something differently).
Get rid of require 'rubygems' from the first line - we're using Bundler so it's not necessary.
Next, cut and paste all of the 'old' contents of spec_helper.rb into the Spork.prefork block. Since we're running an empty(ish) project, there's nothing special we've added that we need to run on each run using the Spork.each_run block. We can leave that empty.
You'll end up with a spec_helper.rb file that looks like this:
require 'spork'Spork.prefork do # Loading more in this block will cause your tests to run faster. However, # if you change any configuration or code from libraries loaded here, you'll # need to restart spork for it take effect. # This file is copied to spec/ when you run 'rails generate rspec:install' ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} RSpec.configure do |config| # == Mock Framework # # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: # # config.mock_with :mocha # config.mock_with :flexmock # config.mock_with :rr config.mock_with :rspec # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures" # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false # instead of true. config.use_transactional_fixtures = true endendSpork.each_run do # This code will be run each time you run your specs.endHead back to your shell and the root of your project and run spork:
Using RSpecLoading Spork.prefork block...Spork is ready and listening on 8989!
Now we're cooking with gas. Open another shell, head to the root of your project, and run watchr .watchr too. Then head to spec/models/person_spec.rb in your text editor and re-save it (or even make a change if you want). Your specs run but.. they're no faster! What's wrong?
It turns out we need to make another change so that RSpec knows we're running Spork. Edit the .rspec file (mentioned earlier) and add --drb to the line (so it probably reads --colour --drb). Now, edit the spec again, save, and.. fast!
You should note that if you use rake at this point to run your entire suite, it'll still not be particularly fast because rake itself is initializing Rails in order to do its job. But if you want to run your entire suite quickly, just run:
rspec spec
With our dummy app and on my machine, this runs in a wallclock time of 0.759s - a serious improvement over 5.2 seconds.
We have Rails 3, RSpec 2, watchr, spork, and SUPER-DUPER FAST SPECS all running on Ruby 1.9.2. Score!
A minor snafu will remain, though. If you update app/models/person.rb, the change won't take effect in your tests since Spork has the old Person still in memory. One way around this is to edit config/environments/test.rb and change:
config.cache_classes = true
To:
config.cache_classes = false
Now your app's classes are reloaded when necessary.
<center>
</center>
It's been a dies horribilis for MRI Ruby today with two new security vulnerabilities forcing the release of 3 new recommended production versions of the de facto official Ruby interpreter. The first, a vulnerability in FileUtils.remove_entry_secure affects both 1.8 and 1.9 branches, while the second, a $SAFE mode vulnerability, affects only 1.8.
The FileUtils Vulnerability (1.8 and 1.9)
Urabe Shyouhei of the Ruby core team has announced that FileUtils is vulnerable to symlink race attacks and he's not talking about hate crimes. Ruby versions including and prior to Ruby 1.8.6p420, Ruby 1.8.7p330, Ruby 1.9.1p430 and Ruby 1.9.2p136 are affected so you're almost guaranteed to be affected.
The problem is FileUtils#remove_entry_secure, a method that was meant to be more secure than its sibling FileUtils#remove_entry. What the remove_entry* methods do is to 'remove' an entry in the local file system. The problem, though, is that remove_entry_secure's security wasn't quite good enough and it could be used by local users to delete arbitrary files and directories. Not a great feature.
The $SAFE Vulnerability (1.8 only)
Ruby's "safe levels" provide a way for you to make the Ruby interpreter more "paranoid" about operations it can perform and the data it can process. There are five levels and they progressively lock down what Ruby will accept - particularly useful if it's necessary to consider all data to be tainted, for example.
This recent vulnerability plays on the fact that the Exception class can both accept and return a string. The bad part is that Exception wasn't respecting the safe level in terms of keeping the string tainted. Urabe Shyouhei provides this example:
$secret_path = "foo"proc do $SAFE = 4 Exception.new($secret_path).to_s $secret_path.replace("/etc/passwd")end.callopen($secret_path) do # do the dirty hereendThankfully, it only affects Ruby 1.8 (not Ruby 1.9) in the shape of Ruby 1.8.6p420 and earlier and Ruby 1.8.7p330 and earlier. The downside? That covers most Ruby 1.8 installs out there, including the default one with OS X. Get upgrading.
The Solution - New Releases of Ruby
Undoubtedly you have your own ways and means of doing upgrades (using RVM, for example) but Urabe has provided links to the latest builds on the official MRI Ruby site if you want them. Repeated here:
Ruby 1.8.7-p334: http://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p334.tar.gz
Ruby 1.9.1-p431: http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p431.tar.gz
Ruby 1.9.2-p180: http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p180.tar.gz
Last but not least, if you've been wondering why Ruby Inside hasn't updated for two weeks, I have some explaining to do and.. it'll be in a post of its own very soon ;-) Meanwhile, check out RubyFlow's snazzy new design!

Level: Intermediate
For many years, serious database aficionados have preferred the Postgres database system. Its industrial strength many installations store terabytes of data. Its fully open source (not controlled by a predatory corporation). Its fast and easy to use. Full text search is built-in. Its the default database for all applications deployed to Heroku.
In 65 minutes, respected database expert (and world-traveling teacher of The Database is Your Friend workshops) Xavier Shay teaches the most useful and powerful features of Postgres. Youll learn to use the built-in full-text search and optimize it. Youll work with triggers and indexes. Youll save yourself hours of frustration with tips for using Postgres smoothly with Rails 3.
If youre familiar with databases but want to add Postgres to your toolbox, this is the video for you!
Youll learn to:
- Setup full text search
- Optimize search with triggers and indexes
- Use Postgres with Ruby on Rails 3
- Optimize indexes by including only the rows that you need
- Use database standards for more reliable queries
- Write powerful reports in only a few lines of code
- Convert an existing MySQL application to use Postgres
Postgres works well as an auxiliary reporting database or as the main database for your application. Get started today!
Subscribe for your business, as an individual, or buy this screencast for only $12!
Includes a typed transcript.






Level: Intermediate
For many years, serious database aficionados have preferred the Postgres database system. Its industrial strength many installations store terabytes of data. Its fully open source (not controlled by a predatory corporation). Its fast and easy to use. Full text search is built-in. Its the default database for all applications deployed to Heroku.
In 65 minutes, respected database expert (and world-traveling teacher of The Database is Your Friend workshops) Xavier Shay teaches the most useful and powerful features of Postgres. Youll learn to use the built-in full-text search and optimize it. Youll work with triggers and indexes. Youll save yourself hours of frustration with tips for using Postgres smoothly with Rails 3.
If youre familiar with databases but want to add Postgres to your toolbox, this is the video for you!
Youll learn to:
- Setup full text search
- Optimize search with triggers and indexes
- Use Postgres with Ruby on Rails 3
- Optimize indexes by including only the rows that you need
- Use database standards for more reliable queries
- Write powerful reports in only a few lines of code
- Convert an existing MySQL application to use Postgres
Postgres works well as an auxiliary reporting database or as the main database for your application. Get started today!
Subscribe for your business, as an individual, or buy this screencast for only $12!
Includes a typed transcript.






Level: Intermediate
You may not know it, but youve probably used software written by John Barnette. Hes a committer to RubyGems. His initial attempt at fixing the test fixture problem shipped with Rails 2 over three years ago.
Whenever I code with John, I always walk away with something practical that I can use in my web applications.
This screencast is part of a new series at PeepCode where we sit down with expert programmers and watch them work. The point isnt to create a deployable product, but rather to discover workflow tips and development hacks that usually require years of experience to figure out.
In this hour and fifty minute screencast, John tries to build a simple group chat application. And amazingly, he actually completes a prototype and deploys it! If youre like us, youll learn something useful whether or not you use any or all of:
- Ruby
- Sinatra
- Git
- Emacs
- The terminal
- RubyGems
- Test driven development with minitest and rack/test
- Heroku deployment
- Pusher real-time push web service
- Isolate, Johns 500 line sandboxing and bundling library
Unlike most other PeepCode Screencasts, we move through this project with only minimal hand-holding. In fact, John even runs into a few problems and has to figure out the solution on his own.
Subscribe for your business, as an individual, or buy this screencast for only $12!







Level: Intermediate
You may not know it, but youve probably used software written by John Barnette. Hes a committer to RubyGems. His initial attempt at fixing the test fixture problem shipped with Rails 2 over three years ago.
Whenever I code with John, I always walk away with something practical that I can use in my web applications.
This screencast is part of a new series at PeepCode where we sit down with expert programmers and watch them work. The point isnt to create a deployable product, but rather to discover workflow tips and development hacks that usually require years of experience to figure out.
In this hour and fifty minute screencast, John tries to build a simple group chat application. And amazingly, he actually completes a prototype and deploys it! If youre like us, youll learn something useful whether or not you use any or all of:
- Ruby
- Sinatra
- Git
- Emacs
- The terminal
- RubyGems
- Test driven development with minitest and rack/test
- Heroku deployment
- Pusher real-time push web service
- Isolate, Johns 500 line sandboxing and bundling library
Unlike most other PeepCode Screencasts, we move through this project with only minimal hand-holding. In fact, John even runs into a few problems and has to figure out the solution on his own.
Subscribe for your business, as an individual, or buy this screencast for only $12!







Level: Advanced, Expert, Double Black Diamond
Gary Bernhardt is the kind of guy who, if you saw him writing code in a coffee shop, would make you want to walk up and ask How did you do that?
In fact, I was with Gary one day when a total stranger asked that after watching him effortlessly wield Vim, Ruby, RSpec, Git, and the command line.
This screencast is part of a new series at PeepCode where we sit down with expert programmers and watch them work. You wont learn a specific topic or build a deployable project, but youll pick up workflow tips and editor hacks that usually require years of experience to figure out.
In this hour and forty minute screencast, we tackle a simple data structure for the sole purpose of watching Gary work out a problem. If youre like us, youll learn something useful whether or not you use any or all of:
- Ruby
- Git
- Vim
- The terminal
- RSpec
- Test driven development
Unlike most other PeepCode Screencasts, we move through this project with only minimal hand-holding. In fact, the protagonists even run into a bit of confusion and have to employ several strategies to get back on track and solve the problem!
Subscribe for your business, as an individual, or buy this screencast for only $12!
The next episode has been published! Catch John Barnette in Play by Play Episode 2!





Jan 24 2012
So far the only gotchas were, I was using the MySQL plugin and not the gem. I’ve since configured my Site5 account to use gems so that’s not a problem and I had a few outdated conventions that I fixed. I’m hoping that I got everything, I mean, after all, my tests passed so everything should be fine! If you guys come across anything out of the ordinary, any error, anything I’d love it if you’d please let me know
Also, I’ve got 6 pounce invites if anyone still is looking for those. :)
I caught up with this thread on Joel’s discussion board today. We software developers will take any opportunity to rant about the bass-ackwards code we have to deal with on a regular basis. For passionate developers, it’s understandable that most code wouldn’t live up to our standardsonly a select few projects have the amount of resources necessary to truly pursue perfection. Over time the exposure to imperfect code can condition us with unfair knee-jerk reaction to new code.
How bad is the code really?
The world is full of terrible code. Usually that becomes painfully obvious at maintenance time. When an existing project is opened up for the first time by a new team member, I think the instinct is to see the flaws before the brilliance. What kinds of things make code stinky? Well it depends who you ask, but some possible reasons are:
- Unnecessary duplication of code (under-abstracted)
- Overly complicated code (over-abstracted or unnecessarily clever)
- Too many files/classes
- Giant monolithic classes
- Wrong design patterns applied
- Stupid algorithms
- Failure to use appropriate libraries or framework features (reinventing the wheel)
- Inconsistency (lack of conventions)
- Numerous obvious comments
- No documentation
Anyone whose done their share of code maintenance has probably been annoyed by most of the things on this list one time or another. “If only they had done it this way.” It’s easy to just assume the code sucks based on a first impression. Once you jump to that conclusion, every minor flaw affirms your prejudice.
Pet peeves
Let’s step back a minute and give ourselves an ego check. To an experienced developer there are hundreds of nuances that will stick out like a sore thumb, but they are likely to annoy you far more than they actually impact your productivity were you to consider them objectively.
If you’re not careful, your concern for the code boils over into judgement of the previous programmers. Maybe the last guy wasn’t up to snuff in this language, maybe his pet peeves were different, maybe he was just a blathering idiot. Whatever the case, why dwell on it?
I’ve managed to make it through a lot of bad code without slowing down much. Every once and a while a refactoring or straight-up delete and rewrite was necessary, but most of the time I was able to grit my teeth and get some changes done relatively quickly.
Real reasons code “sucks”
The problem facing you is likely to be different from what the last programmer faced. It would be foolish to assume that the software was designed with the same requirements that you have in front of you today. Who’s to say the business goals haven’t changed drastically since then?
You and the last developer have different information. Even after you’ve spent a lot of time on the code and understand all the intricacies and business goals, you still may not know the history of the project. Maybe the code has grown and shrunk and morphed into something completely different from when it started. If it’s time to refactor, maybe that’s your job.
It’s also quite possible that refactoring is not worth it. Good developers innately want maintainable and aesthetically pleasing code, but there is a cost. We can’t write perfect software before we understand it, and we can’t refactor without spending time. The developer is usually in a better position than the manager to assess the long-term cost of not refactoring, but he also has a vested interested in exaggerating that cost. To make a fair assessment, the developer must have a direct business interest. Even then there’s a great deal of uncertainty. It’s always a gamble.
Cognitive dissonance
Developers are conditioned to be right. Our job requires a fiercely logical thought process and the ability to make absolute assertions. Being wrong means things are broken, sometimes spectacularly so. And because we think so hard about things in this way, our conclusions are usually well-reasoned. But we are still human, and we still have the same defense mechanisms around our belief systems as everybody else. The insidious thing is that our reasoning blinds us to our own subjectivity. Our open-mindedness is a badge of pride, but also a set of subconscious blinders.
The only really objective thing about software is its output.
Software engineering is about making choices. Some choices are pragmatic (C++ for performance), some are philosophical (Ruby vs Python), but most are an intangible mixture of past experience and future expectations. When you see some code for the first time, the chances that it will mesh with your experience and philosophy are pretty slim. Eventually you may come to appreciate it for what it is, but in the meantime every tradeoff that didn’t follow your current line of thought will irk you.
Software is messy
None of this is to say that there aren’t real quality problems in the software industryof course there are. But I think it’s worth carefully considering our own motivations and biases before judging how bad the problem really is.
We may not like dealing with inadequately-funded balls of mud, but that’s probably where most of the paying work is. Even in relatively clean code bases, reasonable people can disagree on style or architecture points. Regardless of initial code quality, there will always be difficult and inelegant maintenance that needs to be done. My goal is to keep emotion out of it, and just fix problems. Refactoring is great if a business case can be made, otherwise just slog through as fast as possible without complaining.
Easier said than done, I know.
Ruby's issue tracker will be down from 2011-02-23 10:00+09:00 to 24:00 for planned maintenance.
If you have any issue to report, I am afraid but please post a mail to ruby-core mailing list or wait for my finishing maintenance.
Detailed description
In Ruby's $SAFE semantics, safe level of 4 is used to run a untrusted code (such as plugin). So in upper safe levels, some sort of operations are prohibited to prevent untrusted codes from attacking outer (trusted) data.
Exception#to_s was found to be problematic around it. The method can trick safe level mechanism and destructively modifies an untaitned string to be tainted. With this an attacker can modify arbitrary untainted strings like this:
$secret_path = "foo"proc do $SAFE = 4 Exception.new($secret_path).to_s $secret_path.replace "/etc/passwd"end.callopen($secret_path) do ...endAffected versions
Luckily this attack is ineffective for 1.9.x series of ruby. Affected versions are restricted to:
- Ruby 1.8.6 patchlevel 420 and all prior versions
- Ruby 1.8.7 patchlevel 330 and all prior versions
- Development versions of Ruby 1.8 (1.8.8dev)
Solutions
Please upgrade to a newer version.
Updates
- 1.8.7-334 was released to fix this issue. 1.8.7 users are encouraged to upgrade.
A symlink race condition vulnerability was found in FileUtils.remove_entry_secure. The vulnerability allows local users to delete arbitrary files and directories.
Affected versions
- Ruby 1.8.6 patchlevel 420 and all prior versions
- Ruby 1.8.7 patchlevel 330 and all prior versions
- Development versions of Ruby 1.8 (1.8.8dev)
- Ruby 1.9.1 patchlevel 430 and all prior versions
- Ruby 1.9.2 patchlevel 136 and all prior versions
- Development versions of Ruby 1.9 (1.9.3dev)
Solutions
We have fixed this situation. All affected users are encouraged to upgrade their ruby installation.
But please also note, that symlink race attacks are unavoidable when any of upper directories from where you want to delete are owned by someone you cannot trust. So if you want to be secure, you must ensure that ALL parent directories cannot be moved by other untrusted users. For example, parent directories should not be owned by untrusted users, and should not be world writable except when the sticky bit set.
Updates
- Fixed typo. (vulnerabile -> vulnerable)
- 1.8.7-334 was released to fix this issue. 1.8.7 users are encouraged to upgrade.
- 1.9.1-p431 was released to fix this issue. 1.9.1 users are encouraged to upgrade.
- 1.9.2-p180 was released to fix this issue. 1.9.2 users are encouraged to upgrade.
- Fixed affected versions for 1.9 series.
This is the second release of Ruby 1.9.2. It fixes many bugs found in 1.9.2-p0. See ChangeLog for more detail.
Download
<!-- RDLabel: "Download" -->- <URL:http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p136.tar.bz2><dl>
- SIZE:
<!-- RDLabel: "SIZE:" -->- 8819324 bytes
- MD5:
<!-- RDLabel: "MD5:" -->- 52958d35d1b437f5d9d225690de94c13
- SHA256:
<!-- RDLabel: "SHA256:" -->- 33092509aad118f07f0483a3db1d4c5adaccf4bb0324cd43f44e3bd3dd1858cb
</dl> - <URL:http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p136.tar.gz><dl>
- SIZE:
<!-- RDLabel: "SIZE:" -->- 11155066 bytes
- MD5:
<!-- RDLabel: "MD5:" -->- 6e17b200b907244478582b7d06cd512e
- SHA256:
<!-- RDLabel: "SHA256:" -->- c4314df44f3ab81230685fb51c296ce21034f4c719e2fcc0baba221d19f28746
</dl> - <URL:http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p136.zip><dl>
- SIZE:
<!-- RDLabel: "SIZE:" -->- 12566581 bytes
- MD5:
<!-- RDLabel: "MD5:" -->- f400021058e886786ded510a9f45b2c6
- SHA256:
<!-- RDLabel: "SHA256:" -->- 84ffc047b29032ba848dbbf50d3302de7ac732db1448e57303c27ad4b47c2c5b
</dl>
Here you are an annual release of 1.8.7 updates.
Downloads
- ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p330.tar.gz
- ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p330.tar.bz2
- ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p330.zip
Checksums
MD5(ruby-1.8.7-p330.tar.gz)= 50a49edb787211598d08e756e733e42eSHA256(ruby-1.8.7-p330.tar.gz)= 6c261a463b5ffce1dc0920c980218379479dbdf94866d5ed53f1c71f1407c561SIZE(ruby-1.8.7-p330.tar.gz)= 4873383MD5(ruby-1.8.7-p330.tar.bz2)= 2689719fb42c8cf0aa336f8c8933f413SHA256(ruby-1.8.7-p330.tar.bz2)= 486c73b023b564c07e062e2e61114e81de970913b04fac6798d0fbe8b7723790SIZE(ruby-1.8.7-p330.tar.bz2)= 4191156MD5(ruby-1.8.7-p330.zip)= 537d424438a0fefe40bed91b022592d6SHA256(ruby-1.8.7-p330.zip)= 18df0d26d10a9be32275ba7b39ffd222a153fcc4669e4b772eab142d7e7bde90SIZE(ruby-1.8.7-p330.zip)= 5972777It is worth noting that, though Ruby project experienced license change recently (from GPLv2 to 2-clause BSDL) and this is the first time since then to release something, that change do not reach to already-released versions like 1.8.7, matz said to us. So you do not have to worry about it. If you are already using 1.8.7, you can continue using it.
Thank you, happy holidays.






