Ruby Banter #011

Thijs van der Vossen, 04 May 2008, 12:09 in ruby on rails and video (edit).

In this episode, Manfred answers some questions from our viewers about last week’s episode where Eloy defined a method called ‘Object’.

Eloy and Manfred

No comments yet

Ruby Banter #010

Thijs van der Vossen, 29 Apr 2008, 20:47 in ruby on rails and video (edit).

In this episode, Eloy shows how to set up a class with default attributes in a single line of code.

Manfred and Eloy

3 comments

Ruby Banter #009

Thijs van der Vossen, 21 Apr 2008, 11:08 in ruby on rails and video (edit).

In Smalltalk code and data are always kept together. In Ruby this isn’t the case. In this episode, Manfred looks at a poor man’s version of keeping your data with your code.

Manfred and Eloy

8 comments

Using Passenger on OSX for Rails development

Manfred Stienstra, 16 Apr 2008, 15:08 in ruby on rails (edit).

Lately a few things have been bugging me about Rails development using script/server. First, I can’t test through SSL and for applications who switch between SSL and non-SSL you really want your development environment too look as much like production as possible. And secondly, I have to manually manage my app server with script/server. This is a bit of a pain because some of our applications use ActiveResource to communicate so I need to start several app processes.

Proxying trough Apache solved the SSL problem, but now I had to remember on which ports I had to start my app server.

The solution turned out to be Passenger. First we install the passenger gem and compile mod_passenger.so.

$ gem install passenger
$ passenger-install-apache2-module

After that we turn on Apache at System PreferencesSharingWeb Sharing and edit the webserver configuration. I added everything to /etc/apache2/users/manfred.conf but Apache doesn’t really care where you put it, just remember to load mod_passenger.so before using Passenger specific configuration options.

Set up the Passenger configuration as explained at the end of the install script.

LoadModule passenger_module /Library/Ruby/Gems/1.8/gems/passenger-1.0.1/ext/apache2/mod_passenger.so
RailsSpawnServer /Library/Ruby/Gems/1.8/gems/passenger-1.0.1/bin/passenger-spawn-server
RailsRuby /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby

Make sure our apps run in development mode.

RailsEnv development

Allow Apache serve files from our development directories.

<Directory "/Users/manfred/Code">
    Order allow,deny
    Allow from all
</Directory>

Finally, configure virtual hosts for our various projects.

NameVirtualHost *:80

<VirtualHost *:80>
DocumentRoot "/Users/manfred/Code/project1/public"
ServerName project1.local
</VirtualHost>

<VirtualHost *:80>
DocumentRoot "/Users/manfred/Code/project2/public"
ServerName project2.local
</VirtualHost>

7 comments

May 6th: Rails ‘Morning coffee’ meeting in Amsterdam

Thijs van der Vossen, 15 Apr 2008, 10:40 in ruby on rails and meetings (edit).

It’s time for another ‘Morning coffee’ meeting. You’re invited to come chat with your fellow web developers over a nice cup of coffee.

When: Tuesday, May 6th, 2008, 9:30 AM

Where: The Coffee Company on the corner of the Nieuwe Doelenstraat and the Kloveniersburgwal in Amsterdam.

Please leave a comment if you’re coming, any questions you might have are welcome too.

7 comments

Welcoming Eloy Duran

Thijs van der Vossen, 14 Apr 2008, 11:47 in ruby on rails and business (edit).

We’ve been working with Eloy ever since he impressed us with his RubyCocoa demo at the 2007 RubyEnRails conference, and we are very happy that he recently decided to join the Fingertips team. He is not only a great developer but also a very nice guy. It is a joy to have him on board.

Eloy has been a Ruby developer for over four years. He is an active member of the RubyCocoa community where he started the Rucola project, a project that allows you to write RubyCocoa apps without XCode. He lives in Amsterdam on a boat together with his wife Dionne and their two cats.

2 comments

Fast and easy Rails hosting with Phusion Passenger

Thijs van der Vossen, 09 Apr 2008, 23:43 in ruby on rails and launches (edit).

Today Ninh Bui and Hongli Lai from Phusion visited the Fingertips office to introduce us to their Passenger Apache module for Rails. We’re very impressed with their work; installation and deployment is fast and easy and everything just works out of the box.

These guys did a really important job by completely removing the deployment hassle that has always been associated with Rails. They’ve made Rails deployment boring.

We’ll be testing Passenger on a server that’s running 15 small to medium Rails apps. You can expect an in-depth article about our experiences when Passenger will be released ‘any day now, honestly’.

If you’re interested in using Passenger in a bigger environment (for example, if you’re a shared hosting provider who wants to offer Rails support), you should get in touch with these guys to talk about the professional services they provide. Not only because they’re smart, but also because they’re a lot of fun to chat with. We really enjoyed their company.

1 comment

Ruby Banter #008

Thijs van der Vossen, 10 Mar 2008, 15:08 in ruby on rails and video (edit).

Ruby has dedicated keywords like if and else to define conditional logic. Other languages, like IO, use methods for conditional execution. In this episode Manfred shows how you can use a class in Ruby to do something similar.

Manfred and Sam

No comments yet

Ruby on Rails 2.0

Manfred Stienstra, 09 Dec 2007, 15:52 in ruby on rails (edit).

The release of Rails 2.0 made me realize once more what a great project Rails is.

We’ve seen a lot of changes since 1.0; the community working with and on Rails has grown enormously and Rails is now running some really big sites. Even though this has undoubtedly put pressure on the core team, the feel of the project hasn’t changed much.

In this release most new features were driven by people outside of the core team. This is mostly due to the willingness of the core team to accept patches and interact with the community. That takes dedication.

Most developers on the core team run their applications directly on trunk which means that gem releases are no longer a personal need. This, combined with the fact that people are always looking to get their patch in at the last minute, makes it very hard to get a new major release out the door. I therefore applaud David Heinemeier Hansson for putting his foot down and tagging 2.0 (only to find a small bug and having to tag 2.0.1 a day later). That takes courage.

I’m really happy that the core team has been able to keep Rails fun, because in the end, that’s what drives my productivity as a developer.

No comments yet

December 20th: ‘Morning coffee’ meeting in Amsterdam

Thijs van der Vossen, 04 Dec 2007, 10:57 in ruby on rails and meetings (edit).

It’s time for another coffee morning. Like always you’re invited to come chat about Rails, Django, Seaside and web development in general over a nice cup of coffee.

When: Thursday, December 20th, 2007, 9:30 AM

Where: The Coffee Company on the corner of the Nieuwe Doelenstraat and the Kloveniersburgwal in Amsterdam

Please leave a comment if you’re coming, any questions you might have are welcome too.

10 comments

Ruby Banter #007

Thijs van der Vossen, 03 Dec 2007, 10:49 in ruby on rails and video (edit).

In this episode Sam wonders whether Ruby and Rails are ready for the Enterprise.

Manfred and Sam

11 comments

Sam Aaron joins the Fingertips team

Thijs van der Vossen, 20 Nov 2007, 11:33 in ruby on rails and business (edit).

Please join us in welcoming Sam Aaron to our team.

Sam has been active in the Ruby and Rails communities for some years; he founded the Newcastle Ruby and Rails user group and was a speaker at RailsConf Europe this year. He enjoys writing and regularly publishes Ruby articles for InfoQ. Sam was also the technical reviewer for ‘Beginning Google Maps Applications with Rails and Ajax’ from Apress and a contributor to ‘The Rails Way’ published in the Addison-Wesley Professional Ruby Series .

In addition to being a fond advocate of both Ruby and Rails, Sam is interested in the aesthetics of programming languages, language oriented programming, and domain specific languages, which were the general subjects of his Ph.D. thesis.

Sam loves cycling (which is great here in Amsterdam) and also enjoys getting out into the countryside where he likes to walk, scramble and camp.

4 comments

Effectively using rescue_from

Norbert Crombach, 03 Nov 2007, 15:10 in ruby on rails (edit).

Even though Ryan Daigle already covered it in his usual timely fashion, I’d like to share some real life examples of how we use the relatively new rescue_from functionality.

Because I usually prefer methods that raise exceptions instead of returning a boolean, like, say, save! instead of just save, I thought it would be nice if I could deal with some common exceptions on a higher level. This lead me to write a Rails patch based on the exception_handler plugin, which I previously used in some projects.

A few weeks later the patch found its way into Rails core, just in time for the 2.0 preview release. Now everybody can rewrite this:
class PostsController < ApplicationController
  def create
    @post = Post.create!(params[:post])
  rescue ActiveRecord::RecordInvalid
    render :action => :new
  end

  def update
    @post = Post.find(params[:id])
    @post.update_attributes!(params[:post])
  rescue ActiveRecord::RecordInvalid
    render :action => :edit
  end
end
to something like this:
class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordInvalid do |exception|
    render :action => (exception.record.new_record? ? :new : :edit)
  end
end

class PostsController < ApplicationController def create @post = Post.create!(params[:post]) end def update @post = Post.find(params[:id]) @post.update_attributes!(params[:post]) end end

And it just works.

4 comments

Italy, baby!

Norbert Crombach, 22 Oct 2007, 19:39 in ruby on rails, meetings, and presentations (edit).

In a day or three I will be in Pisa for Rails to Italy where I am giving a talk on Ruby patterns in the Rails internals. Shout if you happen to be in the area and want to meet up, you know how it works.

No comments yet

Patching Rails Edge to stay bug free

Manfred Stienstra, 11 Oct 2007, 21:39 in ruby on rails and tools (edit).

A lot of people are on Rails Edge nowadays. Besides all the nifty new features they also encounter bugs. There are two ways to work around these bugs:

  1. Lock your Rails external to an older revision or freeze it to vendor
  2. Find a patch on Trac or write one of your own and apply it

If you decide to apply patches, you’re going to need some help. Our solution is to put all the patches that need to be applied in vendor/patches and put the following Rake task in lib/tasks/patches.rake:

task :patch => 'patches:apply'

namespace :patches do
  desc "Apply all patches from vendor/patches to root"
  task :apply do
    Dir.chdir(RAILS_ROOT) do
      Dir["vendor/patches/*"].each do |patch|
        system "patch -p0 < \"#{patch}\""
      end
    end
  end

  desc "Revert all patches applied in vendor/plugins and vendor/rails" +
       "through SVN"
  task :revert do
    system "svn revert --recursive vendor/plugins vendor/rails"
  end
end

Assuming you’re using Capistrano 2, you can add the following to your deployment recipe to automatically run the patches for each deployment.


after "deploy:update_code", "deploy:patch"

namespace :deploy do
  task :patch, :roles => :app do
    run "rake patches:apply"
  end
end

Now all you have to do is make sure that all the patches apply cleanly and remove them when they’re accepted into Rails.

No comments yet

Ruby Banter #006

Norbert Crombach, 09 Oct 2007, 14:35 in ruby on rails and video (edit).

Today we bring you the next episode, Function Composition: Redux.

Manfred and Norbert

No comments yet

Ruby Banter #005

Thijs van der Vossen, 24 Sep 2007, 23:10 in ruby on rails and video (edit).

In this episode Manfred shows how you can override the === method on your own classes to do advanced matching.

Manfred and Norbert

7 comments

October 11th: Another ‘morning coffee’ meeting in Amsterdam

Manfred Stienstra, 21 Sep 2007, 15:12 in ruby on rails and meetings (edit).

With the summer vacations behind us it’s time for another coffee morning. Like always you’re invited to come chat about Rails, RailsConf Europe experiences, Django, Seaside and web development in general over a nice cup of coffee.

Last time quite a few people asked me about Seaside, but unfortunately I don’t know that much about it. Anyone with Seaside experience is extra super invited.

When: Thursday, October 11th, 2007, 9:30 AM

Where: The Coffee Company on the corner of the Nieuwe Doelenstraat and the Kloveniersburgwal in Amsterdam

Please leave a comment if you’re coming, any questions you might have are welcome too.

22 comments

We're at RailsConf Europe 2007

Norbert Crombach, 18 Sep 2007, 12:00 in ruby on rails and meetings (edit).

If you also happen to be attending this year’s RailsConf in Berlin, come say hello when you see Manfred or me running around.

Also, good news! While his keynote wasn’t too interesting, DHH did announce that the core team is preparing a Rails 2.0 preview release which they hope to get out by the end of the conference.

5 comments

Hackfest interview

Manfred Stienstra, 03 Aug 2007, 12:45 in ruby on rails (edit).

Martin Sadler from Working With Rails interviewed me for the second time about the Rails Hackfest. In the interview I talk about Hackfest experiences, the Rails community in Amsterdam and my typical working days.

“One of the things I’ve learnt during the Hackfest is that competition isn’t always the best driver for quality.”

Interested? Go and read the entire interview.

2 comments

Ruby Banter #004

Thijs van der Vossen, 26 Jul 2007, 12:09 in ruby on rails and video (edit).

In this episode Norbert shows how memoization is implemented and how you can use it to speed up slow methods.

Manfred and Norbert

5 comments

Quick Fix for acts_as_paranoid

Norbert Crombach, 17 Jul 2007, 08:26 in ruby on rails, testing, and broken (edit).

For those of you on Edge Rails, since changeset [7189] appears to have broken the current acts_as_paranoid we’ve been getting some test errors. There’s a quick patch I wrote available in this Pastie, but because scope_out is now recommended by Rick Olson himself this should only be seen as a migration path. Hopefully this will save you some trouble.

No comments yet

Ruby Banter #003

Thijs van der Vossen, 05 Jul 2007, 14:48 in ruby on rails and video (edit).

Here is the third episode in which Manfred shows how & maps to the to_proc method and what you can do with it.

Manfred and Norbert

7 comments

Helpers are for small snippets of code

Manfred Stienstra, 04 Jul 2007, 15:49 in ruby on rails and practices (edit).

Recently we contracted a local company to help out with a Rails project. Their primary job was to implement payments. During an audit or their work I found the following helper:

module CoursesHelper
  include ActiveMerchant::Billing 
  def issuers
    @gateway = IdealGateway.new(
         :merchant            => IDEAL_MERCHANT_ACCOUNT,
         :sub_id              => IDEAL_SUB_ID,
         :password            => IDEAL_PRIVATE_KEY_PASS,
         :private_cert        => IDEAL_PRIVATE_CERT,
         :language            => IDEAL_LANGUAGE,
         :private_key         => IDEAL_PRIVATE_KEY,
         :authentication_type => IDEAL_AUTHENTICATION_TYPE
    )
    
    list = Array.new()
    begin
      response = @gateway.issuers
      if response.success?
        list=Array.new()
        list.push({"issuerName"=>"Kies uw bank...", "issuerID"=>0})
        list=list + (response.params["list"])
      end
    rescue
      list = [{:issuerName=>"Kies uw bank...", :issuerID=>""},
      {:issuerName=>"ofline Simulator", :issuerID=>"00"}]
    end
    return list.map {|i| [ i["issuerName"], i["issuerID"] ] }

  end
  
end

Helpers are for keeping simple code out of your view. They should never include complicated logic. A helper should be so simple that you’d almost dare to deploy without testing.

Also, because it’s a good idea to keep coupling between classes to a minimum, the payment gateway should only be called from classes directly related to payment processing.

Finally, you don’t want such a large number of constants in your code. There are better ways to store the gateway configuration.

The contracter was asked to solve these issues. The gateway initialization was refactored to only appear once and the gateway object was assigned to a constant named IDEAL_GATEWAY. The code to find all issuers was moved to the Payment model.

class Payment < ActiveRecord::Base
  def self.ideal_issuers
    response = IDEAL_GATEWAY.issuers
    response.params["list"]
  end
end
module CoursesHelper
  
  def issuers
    list=Array.new()
    # 'Kies uw bank' means 'Choose your bank'
    list.push({"issuerName"=>"Kies uw bank...", "issuerID"=>0}) 
    list=list + Payment.ideal_issuers
    return list.map {|i| [i["issuerName"], i["issuerID"]] }
  end
  
end

Unfortunately, the issuers helper still looks more like Python than Ruby. I would have written it like this:

module CoursesHelper
  def issuers
    [['Kies uw bank...', 0]] + Payment.ideal_issuers.map \
      { |i|[i['issuerName'], i['issuerID']] }
  end  
end

I don’t think you should include instructions on how to use a drop-down as one of the options inside it. Furthermore, a default value makes no sense in this case. People always have to choose a bank, otherwise they can’t continue with the payment process.

After some refactoring I was left with the code below. I’ve also moved it to the helpers module for the payments controller, because that’s where the form is rendered.

module PaymentsHelper
  def issuers
    Payment.ideal_issuers.map { |i| [i['issuerName'], i['issuerID']] }
  end
end

8 comments

Ruby Banter #002

Thijs van der Vossen, 28 Jun 2007, 13:48 in ruby on rails and video (edit).

After our presentation at RubyEnRails 2007 we decided to share some of our code snippets with the world. Here is the second episode in which Manfred shows how you can make your objects sortable by defining the boat operator.

Manfred and Thijs

5 comments

July 5th: Next ‘morning coffee’ meeting in Amsterdam

Thijs van der Vossen, 22 Jun 2007, 11:31 in ruby on rails and meetings (edit).

Let’s meet up one more time before the holidays. The goal remains unchanged: a good chat about our experiences with Rails, Django, Seaside and other next generation web frameworks over a strong cup of coffee.

When: Thursday, July 5th, 2007, 9:30 AM

Where: The Coffee Company on the corner of the Nieuwe Doelenstraat and the Kloveniersburgwal in Amsterdam

Please leave a comment to tell us you’ll be there or if you have any questions.

14 comments

Ruby Banter #001

Manfred Stienstra, 21 Jun 2007, 11:53 in ruby on rails and video (edit).

After our presentation at RubyEnRails 2007 we decided to share some of our code snippets from the presentation with the world. Here is the first episode in which Norbert shows function composition in Ruby.

Manfred and Norbert

4 comments

RubyEnRails 2007

Manfred Stienstra, 08 Jun 2007, 17:56 in ruby on rails, meetings, and presentations (edit).

Yesterday the three of us attended RubyEnRails 2007, a Dutch one day conference about Ruby and Rails held in our hometown Amsterdam. We had a great time meeting up with all kinds of Rails developers, almost Rails developers and entrepreneurs.

Nic Williams kicked off the conference being his Australian self and sporting his caboose shirt. In his talk he layed out his views on the future of Rails.

Nic points to his code

Norbert and I did a live hacking session with Ruby, we showed a few ways to clean up your Ruby code and a few ways to make it almost unreadable. I think we lost some people along the way, but I hope everyone enjoyed the talk.

The enterprise controller
Closeup of Norbert
Closeup of Manfred
We lost Geoffrey

One of the things that struck me at the conference was that the talks were really diverse, with lots of real world examples and live coding. As Geoffrey Grosenbach mentioned in his closing talk, this really gave the conference it’s own identity. I hope to see more of this in the future. Next stop, RailsConf Europe.

Geoffrey interviews Robert of Wakoopa

Geoffrey Grosenbach interviews Robert Gaal

The crowd

On the right Justin Halsall

More crowd
Eloy and Nic hacking

Eloy Duran and Nic geeking out after a talk

8 comments

Flex can't do REST

Thijs van der Vossen, 08 Jun 2007, 13:04 in ruby on rails and broken (edit).

If you’re thinking of building a cool snazzy Rich Internet Application front-end in Flex for your RESTful Rails application then please stop dreaming.

There’s no way to extract the headers from an HTTP response in ActionScript 3 so you can’t get the id of a newly created resource from the ‘Location’ header and you can’t tell the difference between a ‘500 Internal Server Error’, a ‘404 Not Found’ or a ‘422 Validation Error’.

There’s also no way to get the response body for anything not in the 2xx range.

Oh, and you can only do a GET or a POST, no PUT or DELETE, at least not without a proxy.

If you can prove me wrong, please do.

15 comments

Ruby Banter – Exploring the Fringes of Ruby

Norbert Crombach, 14 May 2007, 20:22 in ruby on rails and presentations (edit).

In a few weeks Manfred and me are giving a talk on Rubyisms at the Dutch RubyEnRails conference. From the site:

Norbert and Manfred take you on a journey along the coast of Ruby, where they try to uncover gems between the driftwood and seaweed while they steer clear of the word ‘metaprogramming’ with great dexterity.

If you’re in or around Amsterdam on June 7th, do come by. We’re looking forward to it!

2 comments

Code to Test Ratio Showdown

Manfred Stienstra, 03 May 2007, 17:40 in ruby on rails and testing (edit).

We had a little Code to Test Ratio showdown at the office today, probably because there was a woman present. It got me wondering what the Code to Test Ratio for other people is. So everybody, please post the CTTR of your current project in the comments.

Note: in Rails you can find your CTTR with rake stats.

17 comments

We're hiring again

Thijs van der Vossen, 02 May 2007, 12:47 in ruby on rails (edit).

We’re looking for a full-time Ruby on Rails developer.

Send us a link to a publicly available site or application, show us your code, or tell us about open source projects you’ve contributed to. We’d like to see what you’ve done with Rails.

If you’re interested, please send an email to thijs@fngtps.com

No comments yet

Testing with attachment_fu

Manfred Stienstra, 26 Apr 2007, 10:56 in ruby on rails and testing (edit).

When you’re testing uploads with attachment_fu, your files end up in RAILS_ROOT/public by default. This is not very handy because they might override your carefully uploaded bunny pictures in development. You can easily solve this by overriding the full_filename method on your attachment model. Let’s assume you have something like this.

class Asset < ActiveRecord::Base
  belongs_to :post  
  has_attachment :content_type => :image, :storage => :file_system
end

Then you can add the following to the file your tests are defined in:

class Asset
  def full_filename(thumbnail = nil)
    file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix].to_s
    File.join(Dir::tmpdir(), file_system_path, *partitioned_path(thumbnail_name_for(thumbnail)))
  end
end

This will make your files get written to /tmp/public. If you have multiple tests that have to override the attachment class, it’s probably best to put it in a separate file.

6 comments

Quick ActiveSupport::Multibyte glossary trick

Manfred Stienstra, 23 Mar 2007, 14:02 in ruby on rails and unicode (edit).

I was trying to make a glossary of words grouped by their first letter, but I wanted words starting with the letter é grouped with words starting with the letter e. No small feat you might imagine. Wrong.

dict = words.inject({}) do |dict, word|
  letter = word.chars.decompose[0..0].downcase.to_s
  dict[letter] ||= []
  dict[letter] << word; dict
end

The reason this works is that letters like é have a decomposed form in Unicode, this form consists of a latin letter and a accent modifier. I’m not sure what happens if you run Arabic through this code, but we’ll cross that bridge when we get there.

11 comments

OpenSSL::SSL::SSLError with SOAP4r and the Rubyforge gem

Manfred Stienstra, 14 Mar 2007, 10:25 in ruby on rails (edit).

If you’ve installed the Rubyforge gem, which is a dependency of just about every gem in the wild through Hoe, then you might have see the OpenSSL::SSL::SSLError when trying to connect to a server over SSL. This is caused by http_access2 because it refuses to connect with SSL without verifying the certificates.

The problem is a little bit tricky because SOAP4r abstracts you away from http_access2 and that makes it hard to set the proper configuration on the HTTP client. Fortunately SOAP4r has a way to configure it’s subsystem.

Let’s assume that you’ve defined a SOAP::RPC::Driver somewhere.

class WebrApi < ::SOAP::RPC::Driver
  DefaultEndpointUrl = "https://webr.com/api"
  [snip]
end

There are two ways of making the error go away, the first is to tell http_access2 to stop verifying certificates and just get on with the connection.

proxy = WebrApi.new
proxy.options['protocol.http.ssl_config.verify_mode'] = OpenSSL::SSL::VERIFY_NONE

This is not recommended because one of the ideas behind SSL is that you can always verify that you’re talking to the correct server. If you want to keep this feature you will have to tell http_access2 which certificates to use.

proxy = WebrApi.new
client.options['protocol.http.ssl_config.verify_mode'] = OpenSSL::SSL::VERIFY_PEER
client.options['protocol.http.ssl_config.ca_file'] = '/etc/ssl/certs/certification_authority.crt'
client.options['protocol.http.ssl_config.client_cert'] = '/etc/ssl/certs/client.cert'
client.options['protocol.http.ssl_config.client_key'] = '/etc/ssl/certs/client.key'

You can find more advanced configuration examples in the SOAP4r source in sample/soap/ssl.

2 comments

URL encoded semicolons, HTTP Authentication and Safari

Manfred Stienstra, 08 Mar 2007, 21:26 in ruby on rails and broken (edit).

Changeset 6185, or so we assume, broke our fix for Basic Authentication in Safari when using RESTful Rails routes.

Luckily it wasn’t too hard to fix the fix and we’ve decided to make a plugin out of it so we can easily keep the fix in sync with Rails for all our projects. You can find safari_basic_auth_fix in our Subversion repository. The current fix makes sure that semicolons are encoded for every outgoing URL and it decodes the semicolons for all the incoming URLs.

Update: Changeset 6485 removed semicolons as a action separator, so this shouldn’t be a problem anymore once you upgrade to Rails trunk.

3 comments

Using OpenStruct as mock for ActiveRecord

Manfred Stienstra, 07 Mar 2007, 15:53 in ruby on rails and testing (edit).

As you may have noticed OpenStruct#id always returns the object id of the OpenStruct instance, even when you set id.

>> o = OpenStruct.new :id => 2
=> #<OpenStruct id=2>
>> o.id
(irb):4: warning: Object#id will be deprecated; use Object#object_id
=> 9850940

Fortunately there is a simple way around this.

OpenStruct.__send__(:define_method, :id) { @table[:id] }

Now OpenStruct behaves like we want.

>> o.id
=> 2

Note that hash and object_id still work fine. You probably want to keep in mind that we’ve redefined the default OpenStruct behaviour and it might cause problems elsewhere.

1 comment

Things have changed

Thijs van der Vossen, 23 Feb 2007, 21:37 in ruby on rails and meetings (edit).

Again a great meeting. I was amazed to see how much Rails is being used these days.

A little less than a year ago at the first meeting, only a handful of the developers visiting were using Rails professionally. This time I not only wasn’t able to find anyone who was not yet getting paid to write Rails code, but I also talked with folks from three different startups using Rails; soocial, SugarStats, and Wakoopa.

4 comments

Ruby and MySQL encoding flakiness

Manfred Stienstra, 20 Feb 2007, 12:01 in ruby on rails and unicode (edit).

The last few weeks we noticed the dreaded question marks on our sites running against MySQL 5.0. We thought we did everything to make sure our servers, databases, tables, clients and connections understood UTF-8, but somehow connections to the database were reset back to Latin1 after some time.

Instead of trying to fix the problem in Rails/Ruby/libmysql I decided to squash the problem in the MySQL server configuration. By default we were seeing this:

mysql> SHOW VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | latin1 | 
| character_set_connection | latin1 | 
| character_set_database   | latin1 | 
| character_set_filesystem | binary | 
| character_set_results    | latin1 | 
| character_set_server     | latin1 | 
| character_set_system     | utf8   | 
+--------------------------+--------+

So I set the following in /etc/mysql/my.cnf:

[mysqld]
character-set-server = utf8

[client]
default-character-set = utf8

Which forces all the encoding to go to UTF-8 by default:

mysql> SHOW VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | utf8   | 
| character_set_connection | utf8   | 
| character_set_database   | utf8   | 
| character_set_filesystem | binary | 
| character_set_results    | utf8   | 
| character_set_server     | utf8   | 
| character_set_system     | utf8   | 
+--------------------------+--------+

7 comments

Seen this?

Thijs van der Vossen, 15 Feb 2007, 20:21 in ruby on rails (edit).

No comments yet

Please welcome Norbert Crombach

Thijs van der Vossen, 05 Feb 2007, 15:57 in ruby on rails and business (edit).

We’re very happy to welcome Norbert Crombach to the Fingertips team. He started this morning.

Norbert has been working with Ruby on Rails since the very first public release when a good friend – who has since moved to Io – convinced him Ruby really was better than Perl.

Norbert always struck us as a talented and extremely bright developer who seemed to be doing very well on his own. He did however get fed up with the business side of running his own company, which made him decide to join us so he could spend more time doing actual development work.

For the next few months Norbert will be working remotely from Eindhoven while he’s trying to find a place to live here in Amsterdam.

2 comments

Third ‘morning coffee’ meeting in Amsterdam

Thijs van der Vossen, 26 Jan 2007, 08:40 in ruby on rails and meetings (edit).

Time for another one. The goal remains unchanged: a good chat about our experiences with Rails, Django, Seaside and other next generation web frameworks over a strong cup of coffee.

Photo by Rodney Ramdas

When: Thursday, February 22nd, 2007, 9:30 AM

Where: The Coffee Company on the corner of the Nieuwe Doelenstraat and the Kloveniersburgwal in Amsterdam

Please leave a comment to tell us you’ll be there or if you have any questions.

29 comments

Dynamic forms with the repetition model

Manfred Stienstra, 25 Jan 2007, 12:06 in ruby on rails, javascript, and web (edit).

I’m sure we’ve all been there; trying to save a list of associated objects together with the instance they belong to. Fortunately with the right tools this can be really simple.

Let’s assume we have a question in a questionnaire and need to specify an arbitrary number of options to this question. We could construct the following database schema.

create_table :questions do |t|
  t.column :stem,        :text
end

create_table :options do |t|
  t.column :question_id, :integer
  t.column :label,       :text
  t.column :feedback,    :text
  t.column :correct,     :boolean, :default => false
end

There are basically three ways I know about to assign multiple options to a question from one page. The first option is to create a Question instance in the database before rendering the form so we can use remote_form to send an Ajax request and directly associate the Option instance. An advantage of this solution is that all data is directly saved to the database, which makes losing any data less likely. Another advantage is that the functionality is spread nicely over the responsible controllers. First you perform a create on the QuestionsController, after that you perform multiple creates on the OptionsController. The disadvantage is that you have to create a Question with default values or by circumventing the initial validation. This could generate some ‘blank’ Question instances in the database which you will have to garbage collect.

The second option is a slight variation on the first option. Instead of creating a Question to link the Options to you keep all the generated Option id’s in the session and link them to the Question after validation. This solution also benefits from nice separation of concern in the controllers, but on the downside it also leaves you with unlinked Option objects you will have to garbage collect.

The third option is to keep all the information about the Questions and Options in the DOM tree of your from and post it all at once. This used to be hard, requiring a lot of custom JavaScript and browser tricks. Fortunately WHATWG is here to help; Web Forms 2.0 defines a repetition model for repeating form controls. Browser support for these interaction models is years away (except for Opera 9, which has an experimental implementation), that’s why there’s a JavaScript library to accelerate the adaptation.

It’s really easy to use the library in your Rails application. Download the repetitionmodel library, extract the zipfile and put the javascript files in public/javascripts. When you’re done with that we can get back to coding our application. Include the JavaScript file somewhere in your views.

<%= javascript_include_tag 'repetition-model-p' %>

We just mentioned that we want to send the entire form at once, we can use validates_associated to make sure the Question is never saved when the options aren’t valid. This allows you to easily validate all the information from the form at once. The models to go with the database look something like this.

class Question < ActiveRecord::Base
  has_many :options, :dependent => :delete
  validates_presence_of :stem
  validates_associated :options
end

class Option < ActiveRecord::Base
  belongs_to :question
  validates_presence_of :label
end

Build the new and edit forms for the QuestionController like you would normally do. A the bottom of the form we will add the HTML to edit the options.

<h2>Options</h2>
<ol id="options">
  <%= render :partial => 'options/option', :collection => @question.options %>
  <%= render :partial => 'options/option', :object => Option.new,
    :locals => {:option_counter => '[option]'} %>
</ol>
<p><button type="add" template="option">New option</button></p>

The first render is for all the existing options, the second render is for what the repetition model calls a template, the template should always be the last in the list of controls.

In app/views/options/_option.rhtml we put the following. This partial doubles as a template for new controls and as a partial for existing options in the database.

<% if option_counter == '[option]' -%>
<li id="option" repeat="template" repeat-start="0">
<% else -%>
<li repeat="<%= option_counter %>">
<% end -%>
  <div>
    <div><label>Label</label></div>
    <%= text_area_tag "options[#{option_counter}][label]", option.label,
      :rows => 1, :cols => 40 %>
  </div>
  <div>
    <div><label>Feedback</label></div>
    <%= text_area_tag "options[#{option_counter}][feedback]", option.feedback,
      :rows => 1, :cols => 40 %>
  </div>
  <div>
    <label><%= radio_button_tag "options[correct]", option_counter, option.correct?,
      :id => "options_correct_#{option_counter}" %> Correct</label>
  </div>
  <div>
    <button type="remove">Delete option</button>
  </div>
</li>

In the HTML you see some extra attributes used by the JavaScript to determine what to do with them. When the partial is rendered with an new Option, the template is flagged by setting the repeat attribute to template. The id of this element is used as a handle for our controls, in our case this is ‘option’. The repeat-start attribute tells the javascript how many empty controls to generate initially from the template, we don’t want any so we’ve set it to 0. Note that we explicitly set the option_counter to ‘[option]’, this is the variable notation for the repetition model. When a new control is instanciated from the template this variable is replaced by the the index of the new control. The first control gets index 0, the second gets index 1 and so forth.

When the partial is rendered with a collection, the magic variable option_counter is set to the index of the collection every time the partial is rendered. We use this index to set the repeat attribute of the list item, this signals to the JavaScript that this is an already instantiated control. The JavaScript will start counting from the largest index when it instantiates a new control.

Finally we want the user to add and remove option controls in our page, this is done with the ‘New option’ and ‘Delete option’ buttons. Their type attribute signals what we want the JavaScript to do with the repetition blocks. In case of the ‘New option’ button the template attribute tells the JavaScript which template to instantiate.

In addition to managing the controls and template in the DOM tree, the JavaScript also takes care of disabling buttons on appropriate times and setting the CSS display property of the template to none. They really thought of everything.

The advantage of this solution is that you can use all the standard Rails tricks to keep your database clean. The biggest disadvantage is that the create method in your QuestionsController becomes a lot more complex.

Let’s hope native browser implementations follow quickly.

6 comments

Rails 1.2 Released

Manfred Stienstra, 19 Jan 2007, 16:49 in ruby on rails and unicode (edit).

Today the Rails Core Team released Ruby on Rails 1.2. The long awaited new version is of course full of features and fixes. The thing we’re most excited about is the inclusion of ActiveSupport::Multibyte. But it doesn’t stop with multibyte support, Rails now ships with UTF-8 as a default in all parts of the framework, something we couldn’t have dreamed of a year ago.

1 comment

Fingertips is hiring

Thijs van der Vossen, 02 Jan 2007, 12:58 in ruby on rails (edit).

We’re looking for a full-time Ruby on Rails developer. If you’re interested, please send email to thijs@fngtps.com

6 comments

UnSpun encoding problems

Manfred Stienstra, 07 Dec 2006, 12:44 in ruby on rails, web, broken, and unicode (edit).

A few weeks ago Amazon launched UnSpun, a web application to collectively manage lists of all sorts.

During signup I was presented with the following.

Screenshot of UnSpun with a broken letter

I know Internet Explorer fixes a lot of broken encoding by guessing the true encoding for just about everything, maybe that’s why they never noticed during development?

I’ve had this problem myself on a few occasions. Because geographical information is commonly extracted from text files and loaded into a database you always have to be really careful to transcode any data extracted from text files to the same encoding as the database. In the case of ISO-8859-1/15, which is commonly used in west-european countries, there is a really simple oneliner to transcode to utf-8.

source.unpack('C*').pack('U*')

3 comments

HTTP Authentication in OS X is broken for RESTful Rails

Thijs van der Vossen, 30 Oct 2006, 08:47 in ruby on rails and broken (edit).

From the Mac OS X Leopard Technology Overview:

Leopard Server features a built-in installation of the powerful and productive Ruby on Rails web application framework. Ruby on Rails is a full stack framework optimized for sustainable productivity. Leopard Server will ship with Mongrel for simplified development and deployment of web-based applications.

That’s great. I only hope this bug will be fixed too. It would be somewhat ironic if you can’t use HTTP Basic Authentication in Safari with the new RESTful Ruby on Rails urls.

If you have access to the latest pre-release version of Mac OS X Leopard, please visit http://onautopilot.com/test;webkit and let us know if you get asked for a username and password or if it’s still broken.

Update: Tim found that you can make this work by url-escaping the semicolon. Add the following to your ApplicationController in app/controllers/application.rb:

# make HTTP Authentication work on Safari for RESTful Rails
def url_for(options = {}, *parameters_for_method_reference)
  result = super(options, parameters_for_method_reference)
  if request.env['HTTP_USER_AGENT'].to_s.include? 'AppleWebKit' 
    result.is_a?(String) ? result.gsub(';', '%3B') : result
  else
    result
  end
end

4 comments

Quiz

Thijs van der Vossen, 23 Oct 2006, 15:39 in ruby on rails, tools, and launches (edit).

This is from a nice new app we’ve been working on for the last month or so. Any idea what it is and who we’re building this for?

Sneak peek

Update: First right answer gets two great books. Can’t tell you what they are about without giving away the answer, I’m afraid…

17 comments

Screencast Scripting

Manfred Stienstra, 09 Oct 2006, 22:07 in ruby on rails, practices, and video (edit).

Last week I posted a short screencast to show some features of ActiveSupport::Multibyte. After typing through the entire screencast twice I decided to automate the process. Screenager, the automated screencast typer, was born.

Download screencast (QuickTime, 544KB)

You can download Screenager from my personal Subversion repository, you will also need a recent version of ActiveSupport.

svn export https://dwerg.net/svn/screenager/trunk screenager
cd screenager
svn export --force http://svn.rubyonrails.org/rails/trunk/activesupport/lib
./screenager --speed 2 http://www.fngtps.com/files/2/2006/10/activesupport.rb

The version currently in SVN evaluates the Ruby code with eval using a clean binding every time you start a new screenplay. I really wanted to use the Freaky Freaky Sandbox for this, but it’s in heavy development and didn’t run at all when I was coding this. Sandbox and multiline Ruby statements are planned for future versions.

16 comments

Nice meeting, short video

Thijs van der Vossen, 05 Oct 2006, 21:39 in ruby on rails, meetings, and video (edit).

It was a lot of fun chatting with other developers at our second ‘morning coffee’ meeting today. Here’s a short video to give you a feel of the event:

Download video (Quicktime, 1.7MB)

6 comments

ActiveSupport::MultiByte

Manfred Stienstra, 05 Oct 2006, 08:48 in ruby on rails and unicode (edit).

As of revision #5223 ActiveSupport::Multibyte is part of Rails. Now everyone can enjoy multibyte safeness in their applications. Needless to say we are really happy. To show some of the features of Multibyte’s String#chars proxy I’ve put together a short screencast.

If you have any questions about ActiveSupport::Multibyte, please consult the API documentation and the Trac Wiki first. Enjoy.

Download screencast (QuickTime, 1.9MB)

32 comments

The Proxy Pattern in Ruby

Manfred Stienstra, 21 Sep 2006, 13:55 in ruby on rails (edit).

My new favorite idiom to use in Ruby is the proxy pattern. But I’m not using it to reduce the memory footprint or to manage some complex resource. I’m using it to keep the original class clean of my torrent of methods and to make my API easy to use.

One of the biggest problems with adding methods to a core class is the chance of collision with other libraries or code, in order to keep this chance low you don’t want to flood classes with new methods. Imagine we want to perform some textual operations on a String, for example ‘Textilize’ it.

require 'redcloth'
RedCloth.new('h1. Proxies!').to_html

But that doesn’t look very nice, especially if we have to duplicate it. Duplication will get us in trouble when we want to change the parameters we send to RedCloth or when we want to switch to another textile processor.

class Formatters
  def self.textilize(str)
    RedCloth.new(str).to_html
  end
end

Formatters.textilize 'h1. Proxies!'

Even though we packaged the code nicely in a method, I’m still not satisfied. This will require us to type that long classname before every call to textilize. And what if we want to perform a number of operations on the same string? Brackets will have to come into play and Lisp our code.

module Formatters
  def textilized
    RedCloth.new(self).to_html
  end
  
  def unnewlined
    self.gsub!(/\r\n/, "\n")
  end
end

String.send :include, Formatters

"h1. Proxies!\r\n".unnewlined.textilized #=> "<h1>Proxies!</h1>"

Very nice! But there are still some problems with this solution. The formatting methods might accidentally override other methods on String, especially if we define even more of these formatting methods. Even though the methods work on the string, they don’t really have much to do with the String class.

This is where the proxy class comes into the picture, it will only take one method on the String class and work as a portal to all our formatting code. In the process the proxy class is even going to make our solution pluggable.

require 'rubygems'
require 'redcloth'

module Formatting
  class Formatter
    
    def initialize(str)
      @str = str
    end
    
    def to_str
      @str
    end
    alias_method :to_s, :to_str
  end
  
  module StringExtension
    def format
      Formatting::Formatter.new self
    end
  end
  
  def register(mod)
    Formatting::Formatter.send :include, mod
  end
  module_function :register
end

module Formatting::Textilize
  def textilized
    @str = RedCloth.new(@str).to_html
    self
  end
end
Formatting.register Formatting::Textilize

module Formatting::UnNewline
  def unnewlined
    @str.gsub!(/\r\n/, "\n")
    self
  end
end
Formatting.register Formatting::UnNewline

String.send :include, Formatting::StringExtension

See how the well placed self enables us to to chain methods?

"h1. Proxies!\r\n".format.unnewlined #=> #<Formatting::Formatter:0x1087c4c @str="h1. Proxies!\n">
"h1. Proxies!\r\n".format.unnewlined.textilized.to_s #=> "<h1>Proxies!</h1>"

There we go, a nice proxy implementation with all the benefits of the original solution. Unfortunately there are some drawbacks, instead of a String instance the methods return a Formatter instance. The to_str keeps us safe in most cases, like concatenation, but not in all cases. Further cloaking measures are left as an exercise for the reader (hint: method_missing, the boat and Comparable).

If you want to see a really cool proxy implementation, check out ActiveSupport::Multibyte.

No comments yet

Second ‘morning coffee’ meeting in Amsterdam

Thijs van der Vossen, 13 Sep 2006, 12:34 in ruby on rails and meetings (edit).

Since we really enjoyed the first ‘morning coffee’ meeting, it is time for another one. The goal remains unchanged: a good chat about our experiences over a strong cup of coffee.

We have decided, however, to broaden the scope beyong Rails developers. Anyone working with next-generation web application frameworks, like Django or even Seaside, is invited too.

When: Thursday, October 5th, 2006, 9:30 AM

Where: The Coffee Company on the corner of the Nieuwe Doelenstraat and the Kloveniersburgwal in Amsterdam

Please leave a comment to tell us you’ll be there or if you have any questions.

22 comments

Extensive testing

Manfred Stienstra, 12 Sep 2006, 16:04 in ruby on rails and unicode (edit).

Today I’ve been merging the Rails multibyte support from Julik’s unicode hacks plugin into the current edge source. After a few testruns my Mac Mini started complaining about the normalization conformance tests…

Finished in 102.769516 seconds.

460 tests, 353652 assertions, 0 failures, 0 errors

I guess I’ll have to fix the Rakefile so I don’t overheat everyone’s computer.

5 comments

URoR 2: KCODE

Thijs van der Vossen, 12 Sep 2006, 00:33 in ruby on rails and unicode (edit).

URoR stands for ‘Unicode Ruby on Rails’ which is a series on using Unicode with Rails. In this second article I’ll show you how to enable the (somewhat limited) UTF-8 support in Ruby and Rails. (first article)

Let’s break a string

Suppose you’re using the truncate helper like this:

<p><%= truncate 'Iñtërnâtiônàlizætiøn', 12 %></p>

The result is something like:

Iñtërn?

Because the helper truncates the string to 12 bytes, it slices the codepoint for the ‘â’ in halve. The result is an invalid sequence which can’t be rendered.

Fix this by adding the following to the top of config/environment.rb:

# Add basic utf-8 encoding support 
$KCODE = 'UTF8'

And the result will be:

Iñtërnâti…

The string is now truncated to 12 codepoints instead of 12 bytes.

What’s happening here?

Setting KCODE to 'UTF8' tell Ruby that your source code is encoded as UTF-8. Some libraries like CGI and some parts of Rails look at KCODE to find out if they need to process strings in a UTF-8 friendly way.

You can now also require the jcode library you get some basic UTF-8 encoding support in Ruby. More about this in a future article.

Not all is good

Although it’s great that truncate has been fixed to work with UTF-8 you should be aware that this is not the case for all helpers:

<p><%= excerpt 'Iñtërnâtiônàlizætiøn', 'nâtiôn', 2 %></p>

This currently always breaks no matter if KCODE is set or not:

?rnâtiônàl…

You can again get the code from our subversion repository.

No comments yet

Submit your Rails Documentation Project proposals

Thijs van der Vossen, 07 Sep 2006, 11:44 in ruby on rails (edit).

Looks like the caboose folks are ready for Rails Documentation Project proposals. If you want to work on the Rails documentation then please tell a little bit about yourself, why you’re qualified, and what you’d like to work on.

No comments yet

Unicode is part of the solution, not part of the problem

Thijs van der Vossen, 06 Sep 2006, 08:59 in ruby on rails and unicode (edit).

Tim Bray in the (for now) final Ruby Ape Diaries entry (emphasis added):

It’s easy to make people angry about this subject, and some of the angry people have a point; certain aspects of Unicode are, on the surface at least, objectively racist; for example, why does UTF-8 encoding of characters become progressively less efficient as you move from the languages of the Western hemisphere to those of the East?

Having said all that, it is my opinion that Unicode works pretty well, and in terms of making the Internet useful to the many peoples of Earth, is part of the solution, not part of the problem. And for that reason, I think that any language that doesn’t do a real good job at Unicode isn’t a very good citizen. And I think Ruby has a major problem in this area. Solutions are promised; we’ll see. And hey, in a few weeks I’m going to get up a stage in a room in Denver full of Rubyists and talk about this stuff; we’ll see whether they let me out of town alive.

Someone please, please record his talk; I’m really looking forward to what he has to say on the subject.

No comments yet

URoR 1: Set the Content-Type

Thijs van der Vossen, 05 Sep 2006, 00:49 in ruby on rails and unicode (edit).

URoR stands for ‘Unicode Ruby on Rails’ which is going to be a series on using Unicode with Rails. In this first article I’ll show you how to set the Content-Type header so that the browser knows what you’re sending. (second article)

Set it in an after filter

On the web, the One And Only Sensible Encoding for Unicode is UTF-8, so that’s what we’re going to use. First, make sure your editor is set to save all files encoded as UTF-8. Then create a new Rails application and generate a controller called ‘static’ with an ‘index’ action so that we have something to test with.

$ rails uror
$ cd uror/
$ ./script/generate controller static index

Now add the following to app/views/static/index.rhtml (just copy it from this page and paste it into your editor):

<p>Iñtërnâtiônàlizætiøn</p>

Run the Rails application with ./script/server and go to /static/index where you should get something garbled that looks like this:

Iñtërnâtiônà lizætiøn

The problem is that you haven’t told the browser that you’re using UTF-8. Fix this by changing app/controllers/application.rb to:

class ApplicationController < ActionController::Base
  after_filter :set_encoding
  
  protected
  
  def set_encoding
    headers['Content-Type'] ||= 'text/html'
    if headers['Content-Type'].starts_with?('text/') and !headers['Content-Type'].include?('charset=')
      headers['Content-Type'] += '; charset=utf-8'
    end
  end
end

The set_encoding after filter does two things:

  1. It sets the Content-Type header to text/html, but only if no Content-Type header has yet been set. This is exactly what Rails would have done anyway, but we’re doing it here so that…
  2. It adds charset=utf-8 to every Content-Type header for a text type when no charset has yet been set.

If you now reload the page the problem is fixed because the browser is no longer receiving a:

Content-Type: text/html

header, but:

Content-Type: text/html; charset=utf-8

Also set it in your Lighttpd or Apache configuration

It’s a good idea to set the UTF-8 encoding in your web server configuration too. For Apache add the following in public/.htaccess or your main configuration:

AddDefaultCharset utf-8

For Lighttpd, change mimetype.assign in config/lighttpd.conf to:

mimetype.assign = (  
  ".css"        =>  "text/css; charset=utf-8",
  ".gif"        =>  "image/gif",
  ".htm"        =>  "text/html; charset=utf-8",
  ".html"       =>  "text/html; charset=utf-8",
  ".jpeg"       =>  "image/jpeg",
  ".jpg"        =>  "image/jpeg",
  ".js"         =>  "text/javascript; charset=utf-8",
  ".png"        =>  "image/png",
  ".swf"        =>  "application/x-shockwave-flash",
  ".txt"        =>  "text/plain; charset=utf-8"
)

Now all static stuff like 404.html and cached pages are also sent with the correct encoding in the Content-type header.

Even add it to the head

If you want make it easy for people to save your pages to disk and open them with the correct encoding later on, you might want to add the following inside the head element of your html pages:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Always do this last as it may mask any trouble you might be having with the http headers.

Update: You can now get all URoR code from our subversion repository.

Update 2:: The upcoming 1.2 release of Rails will add utf-8 as the default charset for all renders, so you’ll no longer need the after filter.

2 comments

Joel Spolsky got one thing right

Thijs van der Vossen, 01 Sep 2006, 09:11 in ruby on rails and unicode (edit).

Although I fully agree with David that Joel Spolsky’s Language Wars is one of the purest forms of FUD against Ruby and Rails ever, I do think Joel got this one right:

I for one am scared of Ruby because (1) it displays a stunning antipathy towards Unicode […]

Sad as it may be, this fear is mostly justified.

5 comments

Fcgimon updated

Manfred Stienstra, 28 Aug 2006, 16:50 in ruby on rails and tools (edit).

In march I wrote a post about our fcgi monitoring and management tool Fcgimon. Today I fixed some rough edges and decided to call this version 1.0.

The biggest change is the way Fcgimon gathers and presents it’s data from `ps`. Earlier versions would just find all the dispatchers and spawners in the process list and show them. This means that not running application would just not show up in the list. Fcgimon now shows the status of all the configured projects, which makes it easier to detect broken spawners. Fcgimon will still show all fcgi processes and spawners outside of the configured projects, but under the normal list and with a small warning.

Minor changes include memory usage information and in general nicer output.

screenshot of fcgimon

If you like what you see you can download Fcgimon from our Subversion repository.

https://fngtps.com/svn/server-scripts/trunk/fcgimon/

2 comments

MySQL NULL gotcha

Thijs van der Vossen, 28 Aug 2006, 11:09 in ruby on rails (edit).

Never try to find the authenticated user in a Rails app running on MySQL with something like:

@authenticated = Person.find_by_id session[:authenticated_id]

Only use find_by_id if session[:authenticated_id] is not nil:

unless session[:authenticated_id].nil?
  @authenticated = Person.find_by_id session[:authenticated_id]
end

When you do a find_by nil the following query is executed:

SELECT * FROM people WHERE (people.`id` IS NULL) LIMIT 1;

Most of the time this returns an empty set, but if the previous query was an insert into the people table, MySQL will return the row for the last insert. This is because NULL somehow returns the generated id:

mysql> SELECT id FROM people WHERE id IS NULL;
Empty set (0.00 sec)

mysql> INSERT people SET username='bob';
Query OK, 1 row affected (0.08 sec)

mysql> SELECT id FROM people WHERE id IS NULL;
+----+
| id |
+----+
| 11 |
+----+
1 row in set (0.00 sec)

mysql> SELECT id FROM people WHERE id IS NULL;
Empty set (0.00 sec)

It would take some time and determination to exploit this, but it’s certainly not impossible.

Update: This was fixed in Rails just after the release of 1.2.1.

4 comments

Ruby on Rails Development Timeline Fun

Manfred Stienstra, 07 Aug 2006, 10:31 in ruby on rails (edit).

I always follow the Ruby on Rails development timeline to see if my patches get applied and if there are any nice new features. Turns out that apart from the usual stuff, there’s the funnies on page three. Just like in the newspaper.

Changeset 4661 Changeset 4678 Changeset 4700

No comments yet

Paypal and Ruby troubles

Manfred Stienstra, 19 Jul 2006, 12:17 in ruby on rails (edit).

Last week our Paypal integration for Dr Stat suddently started acting up. During posts to the notification URL it threw OpenSSL::SSL::SSLError (unknown protocol) errors. I frantically began searching the web for problems with OpenSSL and Ruby, but I couldn’t find anything.

The solution turned out to be really simple. The Paypal gem had been updated and now supports SSL connections. Apparently it raises exceptions when you don’t use SSL now. So I changed Paypal::Notification.ipn_url from the HTTP to the HTTPS url and everything started working again.

3 comments

Rails ‘show and tell’ podcast

Thijs van der Vossen, 28 Jun 2006, 20:32 in ruby on rails and meetings (edit).

You can now subscribe to our podcast with talks from the Rails ‘show and tell’ meeting:

RSS Subscribe with your default feed reader
RSS Subscribe with iTunes

Right now we only have ‘Unicode in Rails’ available, but you can expect more talks in the coming days. It’s also possible to download individual talks.

1 comment

Rails ‘show and tell’ photos

Thijs van der Vossen, 23 Jun 2006, 09:34 in ruby on rails and meetings (edit).

A big ‘thank you’ to Andy Lo A Foe, Rien Swagerman from Resource Studio, Simon de Haan from Eight Media, Flurin Egger from DigitPaint and Julian ‘Julik’ Tarkhanov for their talks.

We also like to thanks Greenpeace International for letting us use the basement and especially the Application Development Team for helping out with the gear.

More photos can be found in our Rails ‘show and tell’ meeting flickr set.

12 comments

Discussing Unicode for Ruby

Thijs van der Vossen, 21 Jun 2006, 13:15 in ruby on rails, web, and unicode (edit).

The Unicode roadmap thread on the Ruby Lang mailing list is now almost 100 messages long.

Yukihiro Matsumoto (matz):

I am too optimized for Ruby string operations using Regexp.

Tim Bray:

Julian ‘Julik’ Tarkhanov:

I think this thread is going to end the same as the one in 2002 did.

Read the whole damn thing if you want to know more about the gritty details. In case it makes your head hurt, go read On the Goodness of Unicode, Characters vs. Bytes and The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) first.

12 comments

Rails ‘show and tell’ talks

Thijs van der Vossen, 19 Jun 2006, 09:06 in ruby on rails and meetings (edit).

Here’s the list of talks for the Rails ‘show and tell’ meeting.

Introduction from Greenpeace

Martin Lloyd from the Greenpeace International Application Development Team will give a short overview of the work they’ve done with Rails and Django.

Audio (AAC) | Audio (MP3)

Web Services

Andy Lo A Foe will show us how to connect your Rails project to legacy Java and PHP applications using XML-RPC, SOAP and REST-style web services.

Audio with slides (AAC) | Audio (MP3) | Slides (PDF)

Content Management with Rails

Rien Swagerman from Resource Studio will talk about his experiences with building a CMS on Rails that’s tailored to the needs of his design studio.

Audio with slides (AAC) | Audio (MP3) | Slides (PDF)

Why Django?

Simon de Haan from Eight Media will talk about why they choose Django and not Rails as their default web development framework. An excellent opportunity to learn what the other hot new web framework is all about.

Audio with slides (AAC) | Audio (MP3) | Slides (PDF)

Mailing newsletters

Flurin Egger from DigitPaint will talk about the development of EntopicMail, a Rails application for mailing out newsletters that’s currently in use at organisations like Philips, NEN and the dutch Ministry of Health, Welfare and Sport.

Audio with slides (AAC) | Audio (MP3) | Slides (PDF)

Unicode in Rails

Julian ‘Julik’ Tarkhanov will show us why the lack of Unicode support in Ruby is a problem when developing Rails applications. He’ll also talk about how he developed a very nice way to properly handle Unicode data in Rails.

Audio with slides (AAC) | Audio (MP3) | Slides (PDF)

Update: Added audio and slides.

1 comment

An excellent and pragmatic proposal for easier Unicode support in Rails

Thijs van der Vossen, 16 Jun 2006, 10:45 in ruby on rails, web, and unicode (edit).

The current Ruby version has no Unicode String class like in Python or Java. This makes it hard for Rails to support multibyte encodings.

The following code snippet from the truncate helper is a good example:

if $KCODE == "NONE"
  text.length > length ? text[0...l] + truncate_string : text
else
  chars = text.split(//)
  chars.length > length ? chars[0...l].join + truncate_string : text
end

This was added to make the helper work with multibyte characters, but it is far from beautiful.

A few days ago, Julian proposed to add a proxy to the string class for accessing characters instead of bytes. I think this is an excellent and very nice solution.

You access the proxy with the char method on a string object. You can for example get the number of characters with:

text.chars.length

The char method is aliased as u, so you can also write:

text.u.length

Which to me looks even nicer.

Using the proxy, you could replace the six lines of code from the truncate helper with:

text.chars.length > length ? text.chars[0...l] + truncate_string : text

That’s a whole lot more obvious. And don’t be fooled, this is just as fast as the longer version because the