kopongo.com

home

Moving from rails 1.2.3 to rails edge

11 Jul 2007

Moving to edge broke a bunch of stuff, especially a bunch of that code that I had managed to completely forget about.

It's like this. You've been rolling along fine on 1.2.3, and, for some reason, you go to the edge release.

       % rake rails:freeze:edge

Some stuff will break. So, here's what's going out, and how to replace it:

  1. Un-initialized active_resource

This one might happen early. The symptom:

    % ruby script/server
       Exiting
       /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/servers/mongrel.rb:15: warning: already initialized constant OPTIONS
       /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/servers/mongrel.rb:18: undefined method `options' for []:Array (NoMethodError)

Weird. Something with mongrel? Let's try webrick:

    % ruby script/server webrick
      => Booting WEBrick...
       /usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/servers/webrick.rb:11: warning: already initialized constant OPTIONS
       /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- active_resource (MissingSourceFile)

This seems to be because the original rake rails:freeze:edge done forgot to bring the activeresource library into the mix. The fix is quick:

      % svn export http://dev.rubyonrails.org/svn/rails/trunk/activeresource vendor/rails/activeresource
  1. Cookies needed some new password.

What is this? Turns out all you need to do for this is to add a little config item to the environment.rb Like this:

    config.action_controller.session = {:session_key => "_myapp_session", :secret => 'this_can_be_long'}
  1. pagination

Remember all that code the scaffolding used to spit out. Some of it, including the pagination, is still sitting around in a lot of places. It seems that pagination got a bad rap in the meantime, and it has now been taken out of edge. So, how do you replace them? The rails deprecations page is not exactly very helpful.

Well, quite a few choices are around. Quite a few people seem to have stepped in to provide this lost functionality, and it's a matter of choosing the plugin. One is [will_paginate]will_paginate, another is paginating_find, and yet another is the paginator gem.

I did not have the time to test them all out (trying to move on, you know?), so I looked through a couple articles and discussions, and picked the will_paginate. Hardly any changes needed, and seems to work fine. Nice work.

  1. Webservices

Yep, webservices are still around, but edge is not all that interested in loading them. The initialization failed. Looking in the code, the webservices were not even in the rake:freeze list .

Ok, so do it manually:

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

Try again: nothing. Fine, google the thing. Looks like someone ran into this problem. He's got the fix all documented there.

  1. push_with_attributes changes

The push_with_attributes call is out. If you have a join table with any extra non-joining columns in it (and therefore not a 'pure' join), you cannot use the push_with_attributes call to save those values anymore.

saving objects:

Something that used to work in 1.2.3 was this: let's say you have you have some golf website, where you are keeping track of how far a player hits a ball with a given club.

Your database would be setup something like this: table player (id, name), table clubs (id, name), and finally table player_club_performance (id, playerid, clubid, distance) to tie them together.

    player = Player.new(:name => 'Tiger')
    player.club_performance.create(:club_id => 7, :distance => 190)

This seems to save the record (the player_club_performance row) immediately. Since player has not yet been saved, it does not have an id, assigned to it. Therefore, if you have any db constraints on that table, something like club_id not null (you should, it's safer that way), this will crash.

If you use method build instead, it just creates the object. When you call p.save (the player), it will save the other associated objects as well.

    player = Player.new(:name => 'Me')
    player.club_performace.build(:club_id => 7, :distance => 300)
    player.save # saves player and club_performance
  1. Sessions

Don't know what happened to this one. I have always used the default file session, but this broke. First, I never noticed any files getting generated in the tmp/sessions directory. Second, on some actions where a bunch of stuff is saved in the session, I would get this:

    [2007-07-06 16:50:13] FATAL  DISPATCHER FAILSAFE RESPONSE (has cgi) Fri Jul 06 16:50:13 +0000 2007
    Status: 500 Internal Server Error
         CGI::Session::CookieStore::CookieOverflow             
           .../vendor/rails/actionpack/lib/action_controller/session/cookie_store.rb:91:in 'close'

This one might be a bug in the edge. I tried setting it to CGI::Session::PStore (as per AWDWR 2, pg 440), but it seemed not to know what that was. It seems defined in the vendor/rails/actionpack/lib/actioncontroller/cgiext/session.rb, but did not pick it up. I looked around at the loading/initialization of this for a bit, the just switched to the database session, which worked fine the first time.

  1. Other random stuff