Sep 10

Rails 3 Theme Support

A few months back I set out to port theme_support (my rails plugin to allow one app to serve different views under various conditions) to Rails 3. I got some basics working, but realised along the way that it was well overdue for a complete rewrite. And then I got busy with projects that didn’t use theme_support and the rewrite was left lingering.

With Rails 3’s official release a few weeks back I began getting a few requests for an updated version. Without time to do the plugin justice, I suggested people fork the project and submit patches. I’m very pleased to say that Lucas Florio took that and ran with it. The result is a new gem: themes_for_rails.

If you’re wanting theme support in a Rails 3 app, that’s the place to go.

Jun 10

Inline Attachments for ActionMailer

The changes to ActionMailer coming in Rails 3 are already a huge improvement, and I hadn’t expected to see much more development before version 3 lands, but it’s great to see this change making it far easier to support inline attachments.

May 10

has_many_polymorphs and Rails 3

I’m gradually porting a number of my older Rails apps over to Rails 3. The main motivation is a chance to really put the new version through its paces, get a better sense of how it’s working, where plugins are at, etc; but it’s also rather nice to get some of the performance improvements and cleaner code along the way.

Catapult relies on Evan Weaver’s has_many_polymorphs plugin quite extensively so it was important to be have a Rails 3 compatible version. I couldn’t find any evidence that anyone else was working on it, so I’ve forked the github project and made a few alterations. I’ve set it up to work as a gem (so I can pull in the latest version using bundler) and adjusted to fit the new rails initialization process. It’s rather hacky, but it’s working for me so far.

Evan informs me that he has no plans to work on compatibility, so I’m going to see what time I can find to tidy it up a bit more, make sure the tests are passing, etc. If anyone else is so inclined, I’d love some help with that. You can find my fork on github.

May 10

Ninja Tune XX

Ninja XX Logo

Its been twenty years since Coldcut formed Ninja Tune and they’ve got a lot planned to celebrate that anniversary. There’ll be events, a very special box set, and… a website featuring exclusive giveaways every week for the next twenty weeks. Ninja Tune XX launched at 4pm today.

This is the rush job I’ve referred to in recent weeknotes, and it feels great to have it launched. It’s already attracting quite a bit of traffic and seems to be holding up well sitting on a little dreamhost private server (we needed cheap access to a lot of bandwidth). Under the hood it’s a Rails 3 app talking to MongoDB via mongoid. We’re using devise for authentication, formtastic for forms and InheritedResources to keep controller code to a minimum.

One of the very pleasing things has been how little there is to say about that stack, with the exception of one issue around multiparameter attributes in mongoid it’s all just worked. How nice.

Feb 10

Weekend Links

MockSMTP.app bills itself as “smart and simple e-mail testing for new apps and websites on Mac OS X” and works as a non-delivering SMTP server so you can trap and review any emails your application sends. The instructions describe how to set it up for a Rails app but it should be usable in many contexts.

As with so many of these things, I heard bits and pieces about the Amazon-Macmillan dust-up over the past couple of weeks, but I really appreciate posts like this that lay out a good chunk of the story

node.js has been really exciting to watch over the past few months and it’s exciting to see Plurk adopting it to serve up “Instant conversations using Comet.” Apparently they ported from JBoss Netty over to node.js and saw a 10 times memory saving! Also getting a lot of buzz is redis and Mathias Meyer has a nice piece on “When To Redis“. It sounds like Redis 2 is going to adopt a Virtual Memory approach, a detailed write-up of which can be found here.

I’ve been doing a lot of work with jQuery this week and found this source viewer invaluable as a way of navigating the library.

Matthew from Bytemark–who I host numerous sites with–has been getting cross with people claiming libel but failing to supply URLs for the supposed instances, so he engaged Carter Ruck to help him work out an appropriate position. His writeup is well worth reading if you bear any responsibility for online discussion fora.

The tremors following the Apple iPad announcement continue to be felt including the ongoing debate about flash. It’s good to see a number of voices (such as Jeffrey Zeldman and Dorian Ray) pointing out that Adobe are well positioned to build tools to help with HTML5 adoption. That would seem a good way forward for them, specially as video players like this one demonstrate the goodness awaiting us.

Handling recurring payments (for subscriptions and the like) tends to be a pain. Recurly looks an interesting entry into that space and I’m looking forward to trying it out.

And then of course there’s Rails 3, now in beta. The announcement is on the rails blog, the release notes are a good place to start. Having had some deployment/gem version issues lately I’m very glad to see bundler stabilising.

Jan 10

Friday (ish) links – January 15th 2010

A few random selections from this week’s reading.

Discussions of online privacy continue to rumble on. ReadWriteWeb had a piece about (facebook’s) Mark Zuckerberg repeating the adage that “the age of privacy is over.” Zuckerberg’s comments would appear to continue the confusion around facebook and privacy. Facebook’s popularity is at least in part due to peoples’ perceptions that there is some privacy (or at least control) inherent in it, but they keep eroding that. I deleted my facebook account a few weeks ago, partly because I was tired of negotiating its plethora of options. Twitter’s “always public” or “private” are really so much easier to handle.

Jeremy Gould pointed out O2’s SIM only iPhone plan on twitter the other day. I really wish I could find an equivalent in the US. On our last trip I was carrying two iPhones and a Palm Pre, but ended up buying a $10 virgin mobile phone from Best Buy.

Perhaps the biggest news in web development this week was the release of jQuery 1.4. The full announcement is here. I’m particularly pleased about all events now supporting live(), the improved support for contexts for actions, and the performance speedups, but many of the API changes look very nice. It’s been great to see several meaty blog posts about how some of the new features/improvements were achieved, such as this one on how the live() support works and Ben Nadel’s piece on handling problems with mouseover/mouseout.

In a similar vein I continue to enjoy Yehuda Katz’ coverage of Rails 3, including this piece on ActiveModel. It’s great to finally have a simple way to use AR’s validations, callbacks, etc. outside of ActiveRecord without resorting to nasty tricks. Gabe de Silveira also deserves some credit, not only for his very useful looking validation_scopes gem, but also for a dissection of its writing.

I missed this month’s LRUG but have been reading up on Dragonfly, a ruby library to handle image uploads and produce resized versions on the fly based on directives in a view. Putting that logic in the view makes a lot of sense and I really like the rails integration being handled by inserting rack middleware. I’ll definitely be looking for a project to try it out on.

Ajaxian continues to be the best source for impressive efforts with javascript. This week I was especially taken by efforts to implement audio sampling in firefox.

Fresh from Silicon Roundabout’s appearance in the latest issue of Wired UK, Ben Terrett of RIG has been working on some merchandise. I guess this joke’s just going to keep going.

TinyMCE is now on github. Chances are it’ll remain a pain to use (as are all editors of its ilk) but at least it can be checked out more quickly now.

And of course it’s been impossible to miss the tragedy in Haiti. The past few years have seen really impressive efforts to harness open source tools and techniques for use in disasters. Andrew Turner’s blog is a good stopping off point to find out what the mapping community has been up to.

Dec 09

Upgrading an app to Rails 3.0pre

I used to be a strong adherent to tracking edge rails. Up until the release of rails 2.3 I let most of my frequently updated projects track edge with a vendored copy of rails, and it rarely caused me any trouble. When 2.3 hit I rethought all that.

With Rails 3 development ramping up I suspected there’d be significant disruption taking place; even with comprehensive test suits I didn’t want the headaches of keeping track of that, and I didn’t want to spoil the pleasant surprises I expected when Rails 3 landed.

A year on from the Rails 3 announcement, with that release seemingly approaching, and with a few plugins to keep up to date, it seemed like this Christmas break was the time to start work on porting at least one relatively complex app over and see what it took. So I picked Catapult Magazine (a relatively stable codebase, no impending releases, uses my fork of theme_support) and got to work.

[Please don’t take any of this as authoritative. I’ve not been keeping up with rails-core lately and I’m posting these notes in case they’re useful to someone. Hopefully when Rails 3 is actually released there’ll be clearer and more definitive explanations of the changes.]

I cloned the current rails HEAD into vendor/rails and for good measure used the rails command to create myself a skeleton application elsewhere that I could use for reference. I then called the tried and tested rake rails:update, hoped for the best, and hit my first stumbling block.

The structure of the rails initializers has changed significantly and the usual rake call won’t work. Instead I had to pull config/boot.rb across from my sample app and do a little restructuring of my startup files:

  1. As has been well covered, rails 3 will use the new Gem Bundler and I created a Gemfile in my app’s root folder listing out my gem dependencies, then called ‘gem bundle‘ to pull them all down
  2. Everything is built on rack these days so we need a config.ru file in the root of our rails folder. Mine contains:
      # Require your environment file to bootstrap Rails
      require ::File.expand_path('../config/environment',  __FILE__)
      # Dispatch the request
      run Catapult::Application.instance
  3. Most of what we would have had in config/environment.rb now lives in config/application.rb. Mine looks like:
      require File.expand_path('../boot', __FILE__)
      module Catapult
        class Application < Rails::Application
          config.time_zone = 'UTC'
          config.generators do |g|
            g.orm             :active_record
            g.template_engine :erb
            g.test_framework  :rspec
      # For clearance
      DO_NOT_REPLY = "donotreply@catapultmagazine.com"
  4. With all of that moved, config/environment.rb is now quite minimal:
      # Load the rails application
      require File.expand_path('../application', __FILE__)
      # Initialize the rails application
  5. Each of the files in config/environments needs to be wrapped in a block:
      Catapult::Application.configure do
        # previous contents of file
  6. The Rakefile now looks like:
        require File.expand_path('../config/application', __FILE__)
        require 'rake'
        require 'rake/testtask'
        require 'rake/rdoctask'
  7. I also had to install the i18n gem and moved all my plugins out of the way so I can reintroduce them one-by-one.
  8. Changes to config/routes.rb aren’t essential but I reworked mine following the examples from Yehuda’s blog entry
  9. In Rails 3 RAILS_ROOT has been deprecated in favour of Rails.root and my app relied quite a bit on the former. A quick search & replace sorted that out.

So with all of those changes complete I was able to run rake rails:update to pick up the updated scripts, etc. and a call to script/server launched the app. Kinda. What followed was a long process of confusing errors, almost all of which could be traced back to plugin-related code that needed to be commented out. But once that was taken care of the skeletal remains ran cleanly.

The next step will be trying to get the plugins back in and running cleanly. I’ll try and blog my progress on that as it unfolds.