Thanks!

Posted about 1 year back at Riding Rails - home

Now seems like a good time to thank the community which helped make our new release a reality. Rails 2.0 includes the work of more than 160 individuals who have contributed features through trac and our mailing list. Our user mailing list has 11002 subscribers all helping each other out. The development list has 1847 people helping improve the framework for all the users.

In particular we’d like to single out the following people who top the list of accepted patches

Our community is our greatest asset, and thanks to every single one of you who’s helped out throughout our history.

Essential Rails: Thanks for Coming

Posted about 1 year back at Softies on Rails - Home

Last Friday and Saturday, Jeff and I had the pleasure of holding our Essential Rails workshop here in Chicago, while 25 of you looked on. This was our first two-day affair, and we hope you all learned as much (and had as much fun) as we did. We had a few folks from the Chicago area, as well as many traveling from afar (including Yokahama, Japan!) to be with us... and I hope you all found it to be worthwhile. I was quite impressed by the wide variety of projects our attendees are and will be working on, and we're anxiously awaiting your success stories.

For those who couldn't make it, stay tuned here for details on our next workshop, likely coming early next year.

Essential Rails: Thanks for Coming

Posted about 1 year back at Softies on Rails - Home

Last Friday and Saturday, Jeff and I had the pleasure of holding our Essential Rails workshop here in Chicago, while 25 of you looked on. This was our first two-day affair, and we hope you all learned as much (and had as much fun) as we did. We had a few folks from the Chicago area, as well as many traveling from afar (including Yokahama, Japan!) to be with us... and I hope you all found it to be worthwhile. I was quite impressed by the wide variety of projects our attendees are and will be working on, and we're anxiously awaiting your success stories.

For those who couldn't make it, stay tuned here for details on our next workshop, likely coming early next year.

Efficient Window-Switching in Emacs

Posted about 1 year back at Blog Posts : Nex3

I had a totally awesome post 80% written when I updated Gutsy... and X crashed. That’s not supposed to happen, but it’s what I get for running on the cutting edge. Anyway, I no longer store half-written blogs in /tmp, and I have a shorter post for you instead.

This is just a cool little Emacs customization I came up with.

I tend to use a lot of windows. For non-Emacsers (or Emacsers who have yet to discover this wonderful feature), in Emacs parlance, a “window” is not the same as the things that float around on your desktop and provide a frontend for programs. An Emacs window is a division of the “frame”, which is the same as the things that float around on your desktop.

Each window is a view into another “buffer”, which is the Emacs term for a document you’re editing1. Thus, you can have multiple frames open editing more than one document at a time. Here’s a screenshot of my Emacs window editing this entry and a file from the Haml source (JPEGed for filesize):

Emacs

Using handy keybindings, you can divide a window in half horizontally (C-x 2) or vertically (C-x 3) as many times as you want. C-x 0 merges the window into its parent. I usually have four or more windows open at a time.

I could go on and on about why windows are wonderful. But that’s not what I wanted to talk about.

When you have a bunch of windows open, you tend to want to switch between them. There’s not much point in having them open if you’re not going to use them. Emacs offers a keybinding for this: C-x o, for “other window”. It moves to the next window in the “canonical ordering”, which is determined in a somewhat logical manner.

This is fine, but not great. If you’re switching a lot, a two-key chord is kind of annoying. Plus there’s no way to move backwards.

So I came up with a couple really simple bindings to help remedy this. Here they are:

(defun select-next-window ()
  "Switch to the next window" 
  (interactive)
  (select-window (next-window)))

(defun select-previous-window ()
  "Switch to the previous window" 
  (interactive)
  (select-window (previous-window)))

(global-set-key (kbd "M-<right>") 'select-next-window)
(global-set-key (kbd "M-<left>")  'select-previous-window)

This makes Alt and the right or left arrow keys select forward or backwards in the canonical ordering of the windows. It’s incredibly simple, but much more pleasant and intuitive than C-x o.

Note that the definitions could be different. select-previous-window could be defined as

(defun select-previous-window ()
  "Switch to the previous window" 
  (interactive)
  (other-window -1))

and select-next-window could just be replaced by other-window, which is what C-x o is bound to. I decided to do it this way because (select-window (___-window)) seemed more elegant, and because I liked the symmetry between the two @defun@s.

1 Emacs also uses buffers for all sorts of other purposes. You can have buffers for IRC, buffers for a shell, even buffers for tetris. But usually they’re for editing documents.

Episode 73: Complex Forms Part 1

Posted about 1 year back at Railscasts

Complex forms often lead to complex controllers, but that doesn't have to be the case. In this episode see how you can create multiple models through a single form while keeping the controller clean.

What's New in Edge Rails: Rails 2.0 Preview Release is Here

Posted about 1 year back at Ryan's Scraps

The Rails 2.0 preview release is here. Go get ya some

svn co http://svn.rubyonrails.org/rails/tags/rel_2-0-0_PR

tags: ruby, rubyonrails

What's New in Edge Rails: Rails 2.0 Preview Release is Here

Posted about 1 year back at Ryan's Scraps

The Rails 2.0 preview release is here. Go get ya some

svn co http://svn.rubyonrails.org/rails/tags/rel_2-0-0_PR

tags: ruby, rubyonrails

What's New in Edge Rails: Rails 2.0 Preview Release is Here

Posted about 1 year back at Ryan's Scraps

The Rails 2.0 preview release is here. Go get ya some

svn co http://svn.rubyonrails.org/rails/tags/rel_2-0-0_PR

tags: ruby, rubyonrails

Not on Edge Rails? Check out what the Rails core has cookin!

Posted about 1 year back at fallenrogue articles

This blog is run on Ruby on Rails version 1.2.3 and I pretty much keep it at the latest release. That said, I’ve always got a clone running on edge (not my dev branch… just an edge branch for funzies!) and I’ve got to say I can’t wait to see some of this stuff go official in 2.0.

Check out the Riding Rails post that gives away some of the best stuff that folks (including me) have been clamoring for. And before you give me flack for my patching things myself, I checked the roadmap and much smarter folks, with more time than me, we’re already on it… and I’m patient. :)

#34 thing I’m hyped over? The dropping of the semi-colon in RESTful interfaces. I know it’s small… but that’s going to make me happy. :) Anyway, check it out, start testing it out, report bugs and get ready to ride the Rails to 2.0!

Rails 2.0: Preview Release

Posted about 1 year back at Riding Rails - home

Behold, behold, Rails 2.0 is almost here. But before we can slap on the final stamp, we’re going to pass through a couple of trial release phases. The first is this preview release, which allows you to sample the goodies in their almost finished state.

We might change a few things or add something else, but by and large, this is how Rails 2.0 is going to look and feel. After this release have had a chance to be tried out, we’re going to move to a release candidate or two (or three, depending on how many we need). Then, the final release.

Before the release of 2.0, we’re also going to be putting out 1.2.4, which will include a variety of bug fixes and the last deprecation warnings to get you ready for upgrading an existing application to 2.0 standards.

Enough about process. Let me tell you a little bit about what’s new in Rails 2.0:

Behold, behold, Rails 2.0 is almost here. But before we can slap on the final stamp, we’re going to pass through a couple of trial release phases. The first is this preview release, which allows you to sample the goodies in their almost finished state.

We might change a few things or add something else, but by and large, this is how Rails 2.0 is going to look and feel. After this release have had a chance to be tried out, we’re going to move to a release candidate or two (or three, depending on how many we need). Then, the final release.

Before the release of 2.0, we’re also going to be putting out 1.2.4, which will include a variety of bug fixes and the last deprecation warnings to get you ready for upgrading an existing application to 2.0 standards.

Enough about process. Let me tell you a little bit about what’s new in Rails 2.0:

Action Pack: Resources

This is where the bulk of the action for 2.0 has gone. We’ve got a slew of improvements to the RESTful lifestyle. First, we’ve dropped the semicolon for custom methods instead of the regular slash. So /people/1;edit is now /people/1/edit. We’ve also added the namespace feature to routing resources that makes it really easy to confine things like admin interfaces:

map.namespace(:admin) do |admin|
  admin.resources :products,
    :collection => { :inventory => :get },
    :member     => { :duplicate => :post },
    :has_many   => [ :tags, :images, :variants ]
end

Which will give you named routes like inventory_admin_products_url and admin_product_tags_url. To keep track of this named routes proliferation, we’ve added the “rake routes” task, which will list all the named routes created by routes.rb.

We’ve also instigated a new convention that all resource-based controllers will be plural by default. This allows a single resource to be mapped in multiple contexts and still refer to the same controller. Example:


  # /avatars/45 => AvatarsController#show
  map.resources :avatars

  # /people/5/avatar => AvatarsController#show 
  map.resources :people, :has_one => :avatar

Action Pack: Multiview

Alongside the improvements for resources come improvements for multiview. We already have #respond_to, but we’ve taken it a step further and made it dig into the templates. We’ve separated the format of the template from its rendering engine. So show.rhtml now becomes show.html.erb, which is the template that’ll be rendered by default for a show action that has declared format.html in its respond_to. And you can now have something like show.csv.erb, which targets text/csv, but also uses the default ERB renderer.

So the new format for templates is action.format.renderer. A few examples:

  • show.erb: same show template for all formats
  • index.atom.builder: uses the Builder format, previously known as rxml, to render an index action for the application/atom+xml mime type
  • edit.iphone.haml: uses the custom HAML template engine (not included by default) to render an edit action for the custom Mime::IPHONE format

Speaking of the iPhone, we’ve made it easier to declare “fake” types that are only used for internal routing. Like when you want a special HTML interface just for an iPhone. All it takes is something like this:


  # should go in config/initializers/mime_types.rb
  Mime.register_alias "text/html", :iphone

  class ApplicationController < ActionController::Base
    before_filter :adjust_format_for_iphone

    private
      def adjust_format_for_iphone
        if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
          request.format = :iphone
        end
      end
  end

  class PostsController < ApplicationController
    def index
      respond_to do |format|
        format.html   # renders index.html.erb
        format.iphone # renders index.iphone.erb
      end
    end
  end

You’re encouraged to declare your own mime-type aliases in the config/initializers/mime_types.rb file. This file is included by default in all new applications.

Action Pack: Record identification

Piggy-backing off the new drive for resources are a number of simplifications for controller and view methods that deal with URLs. We’ve added a number of conventions for turning model classes into resource routes on the fly. Examples:


  # person is a Person object, which by convention will 
  # be mapped to person_url for lookup
  redirect_to(person)
  link_to(person.name, person)
  form_for(person)

Action Pack: HTTP Loving

As you might have gathered, Action Pack in Rails 2.0 is all about getting closer with HTTP and all its glory. Resources, multiple representations, but there’s more. We’ve added a new module to work with HTTP Basic Authentication, which turns out to be a great way to do API authentication over SSL. It’s terribly simple to use. Here’s an example (there are more in ActionController::HttpAuthentication):


  class PostsController < ApplicationController
    USER_NAME, PASSWORD = "dhh", "secret" 

    before_filter :authenticate, :except => [ :index ]

    def index
      render :text => "Everyone can see me!" 
    end

    def edit
      render :text => "I'm only accessible if you know the password" 
    end

    private
      def authenticate
        authenticate_or_request_with_http_basic do |user_name, password| 
          user_name == USER_NAME && password == PASSWORD
        end
      end
  end

We’ve also made it much easier to structure your JavaScript and stylesheet files in logical units without getting clobbered by the HTTP overhead of requesting a bazillion files. Using javascript_include_tag(:all, :cache => true) will turn public/javascripts/.js into a single public/javascripts/all.js file in production, while still keeping the files separate in development, so you can work iteratively without clearing the cache.

Along the same lines, we’ve added the option to cheat browsers who don’t feel like pipelining requests on their own. If you set ActionController::Base.asset_host = “assets%d.example.com”, we’ll automatically distribute your asset calls (like image_tag) to asset1 through asset4. That allows the browser to open many more connections at a time and increases the perceived speed of your application.

Action Pack: Security

Making it even easier to create security applications out of the box is always a pleasure and with Rails 2.0 we’re doing it from a number of fronts. Most importantly, we now ship we a built-in mechanism for dealing with CRSF attacks. By including a special token in all forms and Ajax requests, you can guard from having requests made from outside of your application. All this is turned on by default in new Rails 2.0 applications and you can very easily turn it on in your existing applications using ActionController::Base.protect_from_forgery (see ActionController::RequestForgeryProtection for more).

We’ve also made it easier to deal with XSS attacks while still allowing users to embed HTML in your pages. The old TextHelper#sanitize method has gone from a black list (very hard to keep secure) approach to a white list approach. If you’re already using sanitize, you’ll automatically be granted better protection. You can tweak the tags that are allowed by default with sanitize as well. See TextHelper#sanitize for details.

Finally, we’ve added support for HTTP only cookies. They are not yet supported by all browsers, but you can use them where they are.

Action Pack: Exception handling

Lots of common exceptions would do better to be rescued at a shared level rather than per action. This has always been possible by overwriting rescue_action_in_public, but then you had to roll out your own case statement and call super. Bah. So now we have a class level macro called rescue_from, which you can use to declaratively point certain exceptions to a given action. Example:


  class PostsController < ApplicationController
    rescue_from User::NotAuthorized, :with => :deny_access

    protected
      def deny_access
        ...
      end
  end

Action Pack: Miscellaneous

Also of note is AtomFeedHelper, which makes it even simpler to create Atom feeds using an enhanced Builder syntax. Simple example:


  # index.atom.builder:
  atom_feed do |feed|
    feed.title("My great blog!")
    feed.updated((@posts.first.created_at))

    for post in @posts
      feed.entry(post) do |entry|
        entry.title(post.title)
        entry.content(post.body, :type => 'html')

        entry.author do |author|
          author.name("DHH")
        end
      end
    end
  end

We’ve made a number of performance improvements, so asset tag calls are now much cheaper and we’re caching simple named routes, making them much faster too.

Finally, we’ve kicked out in_place_editor and autocomplete_for into plugins that live on the official Rails SVN.

Active Record: Performance

Active Record has seen a gazillion fixes and small tweaks, but it’s somewhat light on big new features. Something new that we have added, though, is a very simple Query Cache, which will recognize similar SQL calls from within the same request and return the cached result. This is especially nice for N+1 situations that might be hard to handle with :include or other mechanisms. We’ve also drastically improved the performance of fixtures, which makes most test suites based on normal fixture use be 50-100% faster.

Active Record: Sexy migrations

There’s a new alternative format for declaring migrations in a slightly more efficient format. Before you’d write:

create_table :people do |t|
  t.account_id  :type => :integer
  t.first_name  :type => :string, :null => false
  t.last_name   :type => :string, :null => false
  t.description :type => :text
  t.created_at  :type => :datetime
  t.updated_at  :type => :datetime
end

Now you can write:

create_table :people do |t|
  t.integer :account_id
  t.string  :first_name, :last_name, :null => false
  t.text    :description
  t.timestamps
end

Active Record: XML in, JSON out

Active Record has supported serialization to XML for a while. In 2.0 we’ve added deserialization too, so you can say Person.new.from_xml(“<person><name>David</name></person>“) and get what you’d expect. We’ve also added serialization to JSON, which supports the same syntax as XML serialization (including nested associations). Just do person.to_json and you’re ready to roll.

Active Record: Shedding some weight

To make Active Record a little leaner and meaner, we’ve removed the acts_as_* features and put them into individual plugins on the Rails SVN repository. So say you’re using acts_as_list, you just need to do ./script/plugin install acts_as_list and everything will move along like nothing ever happened.

A little more drastic, we’ve also pushed all the commercial database adapters into their own gems. So Rails now only ships with adapters for MySQL, SQLite, and PostgreSQL. These are the databases that we have easy and willing access to test on. But that doesn’t mean the commercial databases are left out in the cold. Rather, they’ve now been set free to have an independent release schedule from the main Rails distribution. And that’s probably a good thing as the commercial databases tend to require a lot more exceptions and hoop jumping on a regular basis to work well.

The commercial database adapters now live in gems that all follow the same naming convention: activerecord--adapter. So if you gem install activerecord-oracle-adapter, you’ll instantly have Oracle available as an adapter choice in all the Rails applications on that machine. You won’t have to change a single line in your applications to take use of it.

That also means it’ll be easier for new database adapters to gain traction in the Rails world. As long as you package your adapter according to the published conventions, users just have to install the gem and they’re ready to roll.

Active Record: with_scope with a dash of syntactic vinegar

ActiveRecord::Base.with_scope has gone protected to discourage people from misusing it in controllers (especially in filters). Instead, it’s now encouraged that you only use it within the model itself. That’s what it was designed for and where it logically remains a good fit. But of course, this is all about encouraging and discouraging. If you’ve weighed the pros and the cons and still want to use with_scope outside of the model, you can always call it through .send(:with_scope).

ActionWebService out, ActiveResource in

It’ll probably come as no surprise that Rails has picked a side in the SOAP vs REST debate. Unless you absolutely have to use SOAP for integration purposes, we strongly discourage you from doing so. As a naturally extension of that, we’ve pulled ActionWebService from the default bundle. It’s only a gem install actionwebservice away, but it sends an important message none the less.

At the same time, we’ve pulled the new ActiveResource framework out of beta and into the default bundle. ActiveResource is like ActiveRecord, but for resources. It follows a similar API and is configured to Just Work with Rails applications using the resource-driven approach. For example, a vanilla scaffold will be accessible by ActiveResource.

ActiveSupport

There’s not all that much new in ActiveSupport. We’ve a host of new methods like Array#rand for getting a random element from an array, Hash#except to filter down a hash from undesired keys and lots of extensions for Date. We also made testing a little nicer with assert_difference. Short of that, it’s pretty much just fixes and tweaks.

Action Mailer

This is a very modest update for Action Mailer. Besides a handful of bug fixes, we’ve added the option to register alternative template engines and assert_emails to the testing suite, which works like this:

  1. Assert number of emails delivered within a block: assert_emails 1 do post :signup, :name => ‘Jonathan’ end

Rails: The debugger is back

To tie it all together, we have a stream of improvements for Rails in general. My favorite amongst these is the return of the breakpoint in form of the debugger. It’s a real debugger too, not just an IRB dump. You can step back and forth, list your current position, and much more. It’s all coming from the gracious note of the ruby-debug gem. So you’ll have to install that for the new debugger to work.

To use the debugger, you just install the gem, put “debugger” somewhere in your application, and then start the server with—debugger or -u. When the code executes the debugger command, you’ll have it available straight in the terminal running the server. No need for script/breakpointer or anything else. You can use the debugger in your tests too.

Rails: Clean up your environment

Before Rails 2.0, config/environment.rb files every where would be clogged with all sorts of one-off configuration details. Now you can gather those elements in self-contained files and put them under config/initializers and they’ll automatically be loaded. New Rails 2.0 applications ship with two examples in form of inflections.rb (for your own pluralization rules) and mime_types.rb (for your own mime types). This should ensure that you need to keep nothing but the default in config/environment.rb.

Rails: Easier plugin order

Now that we’ve yanked out a fair amount of stuff from Rails and into plugins, you might well have other plugins that depend on this functionality. This can require that you load, say, acts_as_list before your own acts_as_extra_cool_list plugin in order for the latter to extend the former.

Before, this required that you named all your plugins in config.plugins. Major hassle when all you wanted to say was “I only care about acts_as_list being loaded before everything else”. Now you can do exactly that with config.plugins = [ :acts_as_list, :all ].

And hundreds upon hundreds of other improvements

What I’ve talked about above is but a tiny sliver of the full 2.0 package. We’ve got literally hundreds of bug fixes, tweaks, and feature enhancements crammed into Rails 2.0. All this coming off the work of tons of eager contributors working tirelessly to improve the framework in small, but important ways.

I encourage you to scourger the CHANGELOGs and learn more about all that changed.

So how do I upgrade?*

If you want to move your application to Rails 2.0, you should first move it to Rails 1.2.3. That’ll include deprecation warnings for most everything we yanked out in 2.0. So if your application runs fine on 1.2.3 with no deprecation warnings, there’s a good chance that it’ll run straight up on 2.0. Of course, if you’re using, say, pagination, you’ll need to install the classic_pagination plugin. If you’re using Oracle, you’ll need to install the activerecord-oracle-adapter gem. And so on and so forth for all the extractions.

To install the preview release through gems, do:

gem install rails --source http://gems.rubyonrails.org

To try it from an SVN tag, use:

rake rails:freeze:edge TAG=rel_2-0-0_PR

We’ll also be putting out Rails 1.2.4 shortly which will include a few more deprecations to warn you in time for 2.0.

In any case, as I explained in the beginning, this is a preview release. Use it to get a feel for 2.0. See where your currently application might need tweaks. And try creating a new application from scratch to see the new defaults. In a few weeks we’ll get on with the release candidates.

Thanks to everyone who’ve been involved with the development of Rails 2.0. We’ve been working on this for more than six months and it’s great finally to be able to share it with a larger audience. Enjoy!

Rails 2.0: Preview Release

Posted about 1 year back at Riding Rails - home

Behold, behold, Rails 2.0 is almost here. But before we can slap on the final stamp, we’re going to pass through a couple of trial release phases. The first is this preview release, which allows you to sample the goodies in their almost finished state.

We might change a few things or add something else, but by and large, this is how Rails 2.0 is going to look and feel. After this release have had a chance to be tried out, we’re going to move to a release candidate or two (or three, depending on how many we need). Then, the final release.

Before the release of 2.0, we’re also going to be putting out 1.2.4, which will include a variety of bug fixes and the last deprecation warnings to get you ready for upgrading an existing application to 2.0 standards.

Enough about process. Let me tell you a little bit about what’s new in Rails 2.0:

Behold, behold, Rails 2.0 is almost here. But before we can slap on the final stamp, we’re going to pass through a couple of trial release phases. The first is this preview release, which allows you to sample the goodies in their almost finished state.

We might change a few things or add something else, but by and large, this is how Rails 2.0 is going to look and feel. After this release have had a chance to be tried out, we’re going to move to a release candidate or two (or three, depending on how many we need). Then, the final release.

Before the release of 2.0, we’re also going to be putting out 1.2.4, which will include a variety of bug fixes and the last deprecation warnings to get you ready for upgrading an existing application to 2.0 standards.

Enough about process. Let me tell you a little bit about what’s new in Rails 2.0:

Action Pack: Resources

This is where the bulk of the action for 2.0 has gone. We’ve got a slew of improvements to the RESTful lifestyle. First, we’ve dropped the semicolon for custom methods instead of the regular slash. So /people/1;edit is now /people/1/edit. We’ve also added the namespace feature to routing resources that makes it really easy to confine things like admin interfaces:

map.namespace(:admin) do |admin|
  admin.resources :products,
    :collection => { :inventory => :get },
    :member     => { :duplicate => :post },
    :has_many   => [ :tags, :images, :variants ]
end

Which will give you named routes like inventory_admin_products_url and admin_product_tags_url. To keep track of this named routes proliferation, we’ve added the “rake routes” task, which will list all the named routes created by routes.rb.

We’ve also instigated a new convention that all resource-based controllers will be plural by default. This allows a single resource to be mapped in multiple contexts and still refer to the same controller. Example:


  # /avatars/45 => AvatarsController#show
  map.resources :avatars

  # /people/5/avatar => AvatarsController#show 
  map.resources :people, :has_one => :avatar

Action Pack: Multiview

Alongside the improvements for resources come improvements for multiview. We already have #respond_to, but we’ve taken it a step further and made it dig into the templates. We’ve separated the format of the template from its rendering engine. So show.rhtml now becomes show.html.erb, which is the template that’ll be rendered by default for a show action that has declared format.html in its respond_to. And you can now have something like show.csv.erb, which targets text/csv, but also uses the default ERB renderer.

So the new format for templates is action.format.renderer. A few examples:

  • show.erb: same show template for all formats
  • index.atom.builder: uses the Builder format, previously known as rxml, to render an index action for the application/atom+xml mime type
  • edit.iphone.haml: uses the custom HAML template engine (not included by default) to render an edit action for the custom Mime::IPHONE format

Speaking of the iPhone, we’ve made it easier to declare “fake” types that are only used for internal routing. Like when you want a special HTML interface just for an iPhone. All it takes is something like this:


  # should go in config/initializers/mime_types.rb
  Mime.register_alias "text/html", :iphone

  class ApplicationController < ActionController::Base
    before_filter :adjust_format_for_iphone

    private
      def adjust_format_for_iphone
        if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
          request.format = :iphone
        end
      end
  end

  class PostsController < ApplicationController
    def index
      respond_to do |format|
        format.html   # renders index.html.erb
        format.iphone # renders index.iphone.erb
      end
    end
  end

You’re encouraged to declare your own mime-type aliases in the config/initializers/mime_types.rb file. This file is included by default in all new applications.

Action Pack: Record identification

Piggy-backing off the new drive for resources are a number of simplifications for controller and view methods that deal with URLs. We’ve added a number of conventions for turning model classes into resource routes on the fly. Examples:


  # person is a Person object, which by convention will 
  # be mapped to person_url for lookup
  redirect_to(person)
  link_to(person.name, person)
  form_for(person)

Action Pack: HTTP Loving

As you might have gathered, Action Pack in Rails 2.0 is all about getting closer with HTTP and all its glory. Resources, multiple representations, but there’s more. We’ve added a new module to work with HTTP Basic Authentication, which turns out to be a great way to do API authentication over SSL. It’s terribly simple to use. Here’s an example (there are more in ActionController::HttpAuthentication):


  class PostsController < ApplicationController
    USER_NAME, PASSWORD = "dhh", "secret" 

    before_filter :authenticate, :except => [ :index ]

    def index
      render :text => "Everyone can see me!" 
    end

    def edit
      render :text => "I'm only accessible if you know the password" 
    end

    private
      def authenticate
        authenticate_or_request_with_http_basic do |user_name, password| 
          user_name == USER_NAME && password == PASSWORD
        end
      end
  end

We’ve also made it much easier to structure your JavaScript and stylesheet files in logical units without getting clobbered by the HTTP overhead of requesting a bazillion files. Using javascript_include_tag(:all, :cache => true) will turn public/javascripts/.js into a single public/javascripts/all.js file in production, while still keeping the files separate in development, so you can work iteratively without clearing the cache.

Along the same lines, we’ve added the option to cheat browsers who don’t feel like pipelining requests on their own. If you set ActionController::Base.asset_host = “assets%d.example.com”, we’ll automatically distribute your asset calls (like image_tag) to asset1 through asset4. That allows the browser to open many more connections at a time and increases the perceived speed of your application.

Action Pack: Security

Making it even easier to create secure applications out of the box is always a pleasure and with Rails 2.0 we’re doing it from a number of fronts. Most importantly, we now ship we a built-in mechanism for dealing with CRSF attacks. By including a special token in all forms and Ajax requests, you can guard from having requests made from outside of your application. All this is turned on by default in new Rails 2.0 applications and you can very easily turn it on in your existing applications using ActionController::Base.protect_from_forgery (see ActionController::RequestForgeryProtection for more).

We’ve also made it easier to deal with XSS attacks while still allowing users to embed HTML in your pages. The old TextHelper#sanitize method has gone from a black list (very hard to keep secure) approach to a white list approach. If you’re already using sanitize, you’ll automatically be granted better protection. You can tweak the tags that are allowed by default with sanitize as well. See TextHelper#sanitize for details.

Finally, we’ve added support for HTTP only cookies. They are not yet supported by all browsers, but you can use them where they are.

Action Pack: Exception handling

Lots of common exceptions would do better to be rescued at a shared level rather than per action. This has always been possible by overwriting rescue_action_in_public, but then you had to roll out your own case statement and call super. Bah. So now we have a class level macro called rescue_from, which you can use to declaratively point certain exceptions to a given action. Example:


  class PostsController < ApplicationController
    rescue_from User::NotAuthorized, :with => :deny_access

    protected
      def deny_access
        ...
      end
  end

Action Pack: Miscellaneous

Also of note is AtomFeedHelper, which makes it even simpler to create Atom feeds using an enhanced Builder syntax. Simple example:


  # index.atom.builder:
  atom_feed do |feed|
    feed.title("My great blog!")
    feed.updated((@posts.first.created_at))

    for post in @posts
      feed.entry(post) do |entry|
        entry.title(post.title)
        entry.content(post.body, :type => 'html')

        entry.author do |author|
          author.name("DHH")
        end
      end
    end
  end

We’ve made a number of performance improvements, so asset tag calls are now much cheaper and we’re caching simple named routes, making them much faster too.

Finally, we’ve kicked out in_place_editor and autocomplete_for into plugins that live on the official Rails SVN.

Active Record: Performance

Active Record has seen a gazillion fixes and small tweaks, but it’s somewhat light on big new features. Something new that we have added, though, is a very simple Query Cache, which will recognize similar SQL calls from within the same request and return the cached result. This is especially nice for N+1 situations that might be hard to handle with :include or other mechanisms. We’ve also drastically improved the performance of fixtures, which makes most test suites based on normal fixture use be 50-100% faster.

Active Record: Sexy migrations

There’s a new alternative format for declaring migrations in a slightly more efficient format. Before you’d write:

create_table :people do |t|
  t.column, "account_id",  :integer
  t.column, "first_name",  :string, :null => false
  t.column, "last_name",   :string, :null => false
  t.column, "description", :text
  t.column, "created_at",  :datetime
  t.column, "updated_at",  :datetime
end

Now you can write:

create_table :people do |t|
  t.integer :account_id
  t.string  :first_name, :last_name, :null => false
  t.text    :description
  t.timestamps
end

Active Record: XML in, JSON out

Active Record has supported serialization to XML for a while. In 2.0 we’ve added deserialization too, so you can say Person.new.from_xml(“<person><name>David</name></person>“) and get what you’d expect. We’ve also added serialization to JSON, which supports the same syntax as XML serialization (including nested associations). Just do person.to_json and you’re ready to roll.

Active Record: Shedding some weight

To make Active Record a little leaner and meaner, we’ve removed the acts_as_XYZ features and put them into individual plugins on the Rails SVN repository. So say you’re using acts_as_list, you just need to do ./script/plugin install acts_as_list and everything will move along like nothing ever happened.

A little more drastic, we’ve also pushed all the commercial database adapters into their own gems. So Rails now only ships with adapters for MySQL, SQLite, and PostgreSQL. These are the databases that we have easy and willing access to test on. But that doesn’t mean the commercial databases are left out in the cold. Rather, they’ve now been set free to have an independent release schedule from the main Rails distribution. And that’s probably a good thing as the commercial databases tend to require a lot more exceptions and hoop jumping on a regular basis to work well.

The commercial database adapters now live in gems that all follow the same naming convention: activerecord-XYZ-adapter. So if you gem install activerecord-oracle-adapter, you’ll instantly have Oracle available as an adapter choice in all the Rails applications on that machine. You won’t have to change a single line in your applications to take use of it.

That also means it’ll be easier for new database adapters to gain traction in the Rails world. As long as you package your adapter according to the published conventions, users just have to install the gem and they’re ready to roll.

Active Record: with_scope with a dash of syntactic vinegar

ActiveRecord::Base.with_scope has gone protected to discourage people from misusing it in controllers (especially in filters). Instead, it’s now encouraged that you only use it within the model itself. That’s what it was designed for and where it logically remains a good fit. But of course, this is all about encouraging and discouraging. If you’ve weighed the pros and the cons and still want to use with_scope outside of the model, you can always call it through .send(:with_scope).

ActionWebService out, ActiveResource in

It’ll probably come as no surprise that Rails has picked a side in the SOAP vs REST debate. Unless you absolutely have to use SOAP for integration purposes, we strongly discourage you from doing so. As a naturally extension of that, we’ve pulled ActionWebService from the default bundle. It’s only a gem install actionwebservice away, but it sends an important message none the less.

At the same time, we’ve pulled the new ActiveResource framework out of beta and into the default bundle. ActiveResource is like ActiveRecord, but for resources. It follows a similar API and is configured to Just Work with Rails applications using the resource-driven approach. For example, a vanilla scaffold will be accessible by ActiveResource.

ActiveSupport

There’s not all that much new in ActiveSupport. We’ve a host of new methods like Array#rand for getting a random element from an array, Hash#except to filter down a hash from undesired keys and lots of extensions for Date. We also made testing a little nicer with assert_difference. Short of that, it’s pretty much just fixes and tweaks.

Action Mailer

This is a very modest update for Action Mailer. Besides a handful of bug fixes, we’ve added the option to register alternative template engines and assert_emails to the testing suite, which works like this:

  1. Assert number of emails delivered within a block: assert_emails 1 do post :signup, :name => ‘Jonathan’ end

Rails: The debugger is back

To tie it all together, we have a stream of improvements for Rails in general. My favorite amongst these is the return of the breakpoint in form of the debugger. It’s a real debugger too, not just an IRB dump. You can step back and forth, list your current position, and much more. It’s all coming from the gracious note of the ruby-debug gem. So you’ll have to install that for the new debugger to work.

To use the debugger, you just install the gem, put “debugger” somewhere in your application, and then start the server with—debugger or -u. When the code executes the debugger command, you’ll have it available straight in the terminal running the server. No need for script/breakpointer or anything else. You can use the debugger in your tests too.

Rails: Clean up your environment

Before Rails 2.0, config/environment.rb files every where would be clogged with all sorts of one-off configuration details. Now you can gather those elements in self-contained files and put them under config/initializers and they’ll automatically be loaded. New Rails 2.0 applications ship with two examples in form of inflections.rb (for your own pluralization rules) and mime_types.rb (for your own mime types). This should ensure that you need to keep nothing but the default in config/environment.rb.

Rails: Easier plugin order

Now that we’ve yanked out a fair amount of stuff from Rails and into plugins, you might well have other plugins that depend on this functionality. This can require that you load, say, acts_as_list before your own acts_as_extra_cool_list plugin in order for the latter to extend the former.

Before, this required that you named all your plugins in config.plugins. Major hassle when all you wanted to say was “I only care about acts_as_list being loaded before everything else”. Now you can do exactly that with config.plugins = [ :acts_as_list, :all ].

And hundreds upon hundreds of other improvements

What I’ve talked about above is but a tiny sliver of the full 2.0 package. We’ve got literally hundreds of bug fixes, tweaks, and feature enhancements crammed into Rails 2.0. All this coming off the work of tons of eager contributors working tirelessly to improve the framework in small, but important ways.

I encourage you to scourger the CHANGELOGs and learn more about all that changed.

So how do I upgrade?

If you want to move your application to Rails 2.0, you should first move it to Rails 1.2.3. That’ll include deprecation warnings for most everything we yanked out in 2.0. So if your application runs fine on 1.2.3 with no deprecation warnings, there’s a good chance that it’ll run straight up on 2.0. Of course, if you’re using, say, pagination, you’ll need to install the classic_pagination plugin. If you’re using Oracle, you’ll need to install the activerecord-oracle-adapter gem. And so on and so forth for all the extractions.

To install the preview release through gems, do:

gem install rails --source http://gems.rubyonrails.org

To try it from an SVN tag, use:

rake rails:freeze:edge TAG=rel_2-0-0_PR

We’ll also be putting out Rails 1.2.4 shortly which will include a few more deprecations to warn you in time for 2.0.

In any case, as I explained in the beginning, this is a preview release. Use it to get a feel for 2.0. See where your currently application might need tweaks. And try creating a new application from scratch to see the new defaults. In a few weeks we’ll get on with the release candidates.

Thanks to everyone who’ve been involved with the development of Rails 2.0. We’ve been working on this for more than six months and it’s great finally to be able to share it with a larger audience. Enjoy!

Speaking: QCon San Francisco

Posted about 1 year back at Jay Fields Thoughts

I'm going to be presenting on Business Natural Languages (Domain Specific Languages for Subject Matter Experts) at QCon San Francisco in November.

Ruby's Multithreading: On Processes and Threads

Posted about 1 year back at Ruby Inside

Threadpic

Manuel Holtgrewe presents Ruby's Multithreading: On Processes and Threads, a great look at the processes (pun intended) involved with Ruby's threading system and the difference between kernel level threads and pure user level threads. He then makes an argument why a process oriented system for division of labor can make more sense than a thread oriented one.

Web app idea of the day: estimate and manage home-improvement projects

Posted about 1 year back at opensoul.org - Home

Seth Godin and Ze Frank both tell of the importance of getting your ideas out, either by executing them, or simply telling others about them. The more you do it, the better you will be at it. Very few of the ideas we come up with will ever get executed, so I decided I might as well just get the ideas out and see where they go.

As a new homeowner, I’ve joined the scores of people that have realized that the home-improvement game is one that never ends. I have a long list of improvements that I want to do: new kitchen counters and flooring, windows, a new patio… it goes on and on.

The cost for home improvement is simply cost of materials + labor. Figuring out how much it will cost to replace all the windows in my house is as easy as adding up the cost of the windows, the tools and other materials required, and decided whether I will hire someone to do it, or do it myself.

I want an application that estimates the cost of the projects I’m thinking about doing that includes the required materials and tools.

There are a lot of “project cost estimators” out there, but all of them seem to be provided by contractors, which inherently makes them biased. They also do a very poor job of breaking down why a project actually costs as much as it does, and all of them seem to make the assumption that I will be hiring the contractor to do the work.

The application would allow me to add all of the projects that I want to do, giving a template for each type of project that includes the required materials and tools.

For example, I want to tile my kitchen floor. I could create a new project that would be populated with the common materials required for tiling floors, including the tools (I’m a new homeowner, every project requires a couple new tools). I could then go through the list and customize the materials that I want, or mark off the tools or materials that I already have, removing them from the total cost. Here is a partial list that it would create:

Item Unit Cost Quantity Cost
Tile $1 per sq. ft. 200 sq. ft. $200
Grout $50 per 100 sq. ft. 2 $100
Tape Measure $6 $6
Tile/wet saw $100 $100
Chalk line $10 $10
…
Total $980

Anyone that has ever done a project also knows that it’s not as simple as just choosing the material that you want. There are always options! Do I want the cheap $1 per sq. ft. tile, or do I want the nice $5 per sq. ft. tile? Do I want to buy a tile saw, or rent one? So, as an added bonus, I want the application to allow me to configure different options for the materials and tools, and show me how each option would affect the cost.

Since this would obviously be a Web 2.0™ app, it has to be have a social networking aspect. You could browse other peoples projects, getting ideas for your own. You could use someone else’s project as a template for your own. In time, the app could integrate with other APIs, pulling in photos from Flickr to show the results of the project, or get building materials and costs from online stores. Oh, the possibilities are endless!

So, either someone go build that and let me know when it’s done, or someone with a lot of extra money send it this way and I’ll spend a couple months building it.

What's New in Edge Rails: Your DB Adapter May Have Left the Building

Posted about 1 year back at Ryan's Scraps

If your Rails app happens to be running against an Oracle, SQLServer, or Sybase database and you’re on Edge Rails (or are headed to Rails 2.0) then you’re going to need to make sure you have the correct gems installed on your machine. As of now the database adapters for these databases have been pulled out of the core Rails distribution and are available as gems. One of these should work for you if you rely on one of the affected databases:

1
2
3
gem install activerecord-oracle-adapter
gem install activerecord-sqlserver-adapter
gem install activerecord-sybase-adapter

tags: ruby, rubyonrails


1 ... 512 513 514 515 516 ... 634