Mostly good news about freezing, Typo, and Rails 1.1.1

Let’s start with the good news about freezing and Rails 1.1.1:

  • New applications will automatically bind to the gem version of Rails they were created with using a RAILS_GEM_VERSION constant in config/environment.rb
  • You can now file freeze a new application with rails myapp --freeze, such that it doesn’t even depend on the proper gems being available
  • You can now also freeze Rails from a tag using like rake rails:freeze:edge TAG=rel_1-1-0

So lots of great options to prevent that your application will ever get bitten by an external upgrade again.

In addition, we’re including a handful of fixes for various other regressions. So the vast majority of all applications should Just Work after the upgrade (but of course, you should always test before deploying an update). You may still have plugins that are incompatible, but most plugin authors should have a 1.1.x compatible version available by then.

If you have Typo 2.6.0, you must freeze

Now to the slightly less exciting news: Typo 2.6.0 is not going to work with Rails 1.1.1. The Typo team has been working on a new release that’ll be 1.1.x compatible and I’ve been imploring them to release a 2.6.1 that just includes Rails 1.0 in vendor/rails. But a vanilla 2.6.0 install with not work with 1.1.×.

That sounds worse than it is, because the remedy is really simple: Checkout Rails 1.0 into vendor/rails and Typo won’t give a hoot when your host inevitably decides to upgrade to Rails 1.1.×. The easiest and most fault-tolerant way of doing that is through svn. Go to the root of your Typo application and run:

svn export http://dev.rubyonrails.org/svn/rails/tags/rel_1-0-0 vendor/rails

Then restart your Typo and you’re now safe from gem updates. This antidote is a good one for any application you have deployed on a shared host. It’s not safe, and will never be safe, to just float against the latest Rails on a shared host. Always make sure you’re playing it cool and do a freeze.

Regardless of the factors, the core team apologizes for any inconvenience caused by the 1.1.0 release. While it worked for the vast majority of people, we should indeed had made sure to get feedback from the Typo guys before pushing out the release. Then at least we could have warned people in advance that 2.6.0 was simply not going to jive.

Hopefully this ordeal will motivate more people to help test future release candidates. We’ll do ours to help by extending the testing period and we’ll be grateful if you would do yours by testing and reporting any troubles found.

Rails 1.1.1 early this week

If you want to get into the good spirit right away, you can help test the trunk, which is aiming to become Rails 1.1.1 early this week. We still lack a few fixes, but what’s there should already deal with almost all of the issues. To be fail safe, remove vendor/rails (if you have it), and run:

svn export http://dev.rubyonrails.org/svn/rails/trunk vendor/rails

Thanks everyone!

Production Rails: Rails Training Gets Deeper and More Focused

As the art of Rails development matures, so do the ways we teach and learn about it. Following the release of Rails 1.1, the state of Rails training just took a small step forward along with it.

Mike Clark just announced a new course from the perpetually-sold-out Pragmatic Studio on Production Rails deployment.

Since the release of Rails, teams have been steadily forming around new products and projects in Rails. While there have been a lot of great resources for learning how to do Rails development_, this is the first in a sure-to-be-expanding market for training and documentation on how best to deploy and manage a production Rails application. The course is being taught by Rails Studio veteran and Pragmatic Project Automationkit/au/index.html author Mike Clark and Rails deployment expert (not to mention creator of Tomcat and Ant) James Duncan Davidson.

The location and exact time haven’t yet been decided, so signing up to be notified just may have an impact.

How do you think the training and documentation market for Rails will continue to evolve? What would you like to see next?

Upload Progress Helper and Rails 1.1

One of the casualties of the 1.1 release was the experimental upload progress helper. Unfortunately it didn’t work on all the platforms we support and it was a source of numerous bug reports. After talking with Sean, we decided to remove it from rails’ core.

For those of you who were using it, the code was extracted to a rails plugin. To install it just run the following command and everything will be back where you need it.

./script/plugin install upload_progress

Freeze is cool, so freeze for goodness sake

Many shared hosts did a quick dance up and down at the release of Rails 1.1 because a large number of their customers were floating off the gems, which meant that upgrading the gems automatically updated all the applications. Some applications couldn’t handle the upgrade (most notably Typo), so they broke. And the customers were none too happy and complained to the hosts: “Why oh why, dear host, would you upgrade and break my application?”

This is obviously bad. But nothing is so bad that you can’t learn from it. And this is a wonderful opportunity to learn that You Should Freeze Rails For Any Application In Production. Sure, we talked about that back in December, but talk is cheap (and often overheard).

So here follows a lifted finger and a promise. The lifted finger first:

If thou bless thee world with an application of open source, thou must ship it with the version of Rails that thou knowest it to work with in vendor/rails.

Here’s one counter argument that will not allow you to evade this finger: “But it’ll make my app X% larger to download”. In this day of age, nobody cares. Time is more valuable than disk space and saving hair-pulling aggravation over broken dependencies is infinitely more valuable than disk space.

Then the promise: The next version of Rails will by default extract the version of Rails it was created with into vendor/rails. This will get everyone into the Christmas spirit of being good on day one. It’ll be natural to desire less dependencies and you will soon froth at the notion of a shared host controlling the destiny of your application by choosing to update some gems. And you will be happy and content.

Rails 1.1: The Forgotten Features

Today, Mike Clark follows the release of Rails 1.1 with: Rails 1.1: The Forgotten Features, a writeup of some of the little changes in Rails 1.1 that, though not big enough to make the big list of "wow"s, are sure to make all Rails developers’ lives a little better every day.

Take a look and feel free to suggest additions to the list if you’ve got ’em.

Rails 1.1: RJS, Active Record++, respond_to, integration tests, and 500 other things!

The biggest upgrade in Rails history has finally arrived. Rails 1.1 boasts more than 500 fixes, tweaks, and features from more than 100 contributors. Most of the updates just make everyday life a little smoother, a little rounder, and a little more joyful.

But of course we also have an impressive line of blockbuster features that will make you an even happier programmer. Especially if you’re into Ajax, web services, and strong domain models — and who isn’t these funky days?

The star of our one-one show is RJS: JavaScript written in Ruby. It’s the perfect antidote for your JavaScript blues. The way to get all Ajaxified without leaving the comfort of your beloved Ruby. It’s the brainchild of JavaScript and Ruby mastermind Sam Stephenson and an ode to the dynamic nature of Ruby.

Here goes a few sample rjs calls:

  # First buy appears the cart, subsequent buys highlight it
  page[:cart].visual_effect(@cart.size == 1 ? :appear : :highlight)
  
  # Replace the cart with a refresh rendering of the cart partial
  page[:cart].replace_html :partial => "cart"
  
  # Highlight all the DOM elements of class "product"
  page.select(".product").each do |element|
    element.visual_effect :highlight
  end
 
  # Call the custom JavaScript class/method AddressBook.cancel()
  page.address_book.cancel
  
  # 4 seconds after rendering, set the font-style of all company
  # spans inside tds to normal
  page.delay(4) do
    page.select("td span.company").each do |column| 
      column.set_style :fontStyle => "normal"
    end
  end

And that’s just a tiny taste of what RJS is capable of. It takes the Ajax on Rails experience far above and beyond the great support we already had. Bringing us even closer to the goal of “as easy as not to”. Read more about RJS in the docs or in Cody Fauser’s tutorial about element and collection proxies and his introduction to RJS (it shouldn’t surprise you that Cody is writing about book about RJS for O’Reilly).

But its not just the view we’re giving some tender love, oh no. Active Record has been blessed with bottomless eager loading, polymorphic associations, join models, to_xml, calculations, and database adapters for Sybase and OpenBase. It’s a huge upgrade and made possible through the fantastic work of Rick Olson (who was recently accepted into Rails Core, not a minute too soon!) and Anna Chan. Let’s dig into three of the top features:

Bottomless eager loading gives you the power of pulling back a multi-level object graph in a single JOIN-powered SQL query. Example:

  # Single database query:
  companies = Company.find(:all, :include => { 
    :groups => { :members=> { :favorites } } })
  
  # No database query caused:
  companies[0].groups[0].members[0].favorites[0].name

You can mix’n’match too. Using both multi-level fetches and first-level ones in the same call:

  # Just 1 database query for all of this:
  authors = Author.find(:all, :include => [ 
    { :posts => :comments }, :categorizations ])
  authors[0].posts[0].comments[0].body # => "Rock on Rails!"
  authors[0].categorizations[0].name   # => "Less software"

Polymorphic associations and join models give you access to much richer domains where many-to-many relationships are exposed as real models. Say Authorship between Book and Author:

  class Author < ActiveRecord::Base
    has_many :authorships
    has_many :books, :through => :authorships
  end
 
  class Book < ActiveRecord::Base
    has_many :authorships
    has_many :authors, :through => :authorships
  end
 
  class Authorship < ActiveRecord::Base
    belongs_to :author
    belongs_to :book
  end

…or addresses that can belong to both people and companies:

  class Address < ActiveRecord::Base
    belongs_to :addressable, :polymorphic => true
  end
 
  class Person < ActiveRecord::Base
    has_one :address, :as => :addressable
  end
 
  class Company < ActiveRecord::Base
    has_one :address, :as => :addressable
  end

Now let’s have a look at the new respond_to feature of Action Controller that makes it much easier to launch your application with both Ajax, non-Ajax, and API access through the same actions. By inspecting the Accept header, we can do clever stuff like:

  class WeblogController < ActionController::Base
    def create
      @post = Post.create(params[:post])
  
      respond_to do |type|
        type.js   { render }  # renders create.rjs
        type.html { redirect_to :action => "index" }
        type.xml  do
          headers["Location"] = post_url(:id => @post)
          render(:nothing, :status => "201 Created")
        end
      end
    end
  end

The recently launched API for Basecamp uses this approach to stay DRY and keep Jamis happy. So happy that he wrote a great guide on how to use respond_to

Speaking of Jamis, he also added the third layer of testing to Rails: Integration tests. They allow you to faithfully simulate users accessing multiple controllers and even gives you the power to simulate multiple concurrent users. It can really give you a whole new level of confidence in your application. The 37signals team used it heavily in Campfire from where it was later extracted into Rails. See Jamis’ great guide to integration testing for more.

These highlighted features are just the tip of the iceberg. Scott Raymond has done a great job trying to keep a tab on all the changes, see his What new in Rails 1.1 for a more complete, if brief, walk-through of all the goodies. And as always, the changelogs has the complete step-by-step story for those of you who desire to know it all.

And as mentioned before, Chad Fowler’s excellent Rails Recipes has in-depth howtos on a lot of the new features. If you desire some packaged documentation, this is the book to pick up.

Upgrading from 1.0

So with such a massive update, upgrading is going to be hell, right? Wrong! We’ve gone to painstaking lengths to ensure that upgrading from 1.0 will be as easy as pie. Here goes the steps:

  • Update to Rails 1.1:
    gem install rails --include-dependencies
  • Update JavaScripts for RJS:
    rake rails:update

That’s pretty much it! If you’re seeing any nastiness after upgrading, it’s most likely due to a plugin that’s incompatible with 1.1. See if the author hasn’t updated it and otherwise force him to do so.

If you’re on Ruby 1.8.2 with Windows, though, you’ll want to upgrade to the 1.8.4 (or the script/console will fail). And even if you’re on another platform, it’s a good idea to upgrade to Ruby 1.8.4. We still support 1.8.2, but might not in the next major release. So may as well get the upgrading with over with now.

San Diego Ruby Users Group

There is some action down in San Diego on the Ruby and Rails front. The local RUG, after some time of inactivity, is revving back up. If you live in the area and are keen on meeting up with like minded Rubyists and Railers, take a look over at Kevin Clark’s blog for more information.