Why to wait for rails3, and why not!

Rails3 is on its way and everybody is just waiting for its release. But what can you do in the meantime to cure some obvious mistakes of the current version?

We decided to pick out 3 nice parts of rails3 and use them right now - we just couldn't wait any longer.

  • Bundler The rails gem feature was just a big error. You require a gem, then you want to run rake gem:install and this throws an error because it is missing a gem. Where is the point? Bundler is independent from rails, it is a simple but sufficient solution to really get going with gems (vs. rails plugins). We installed it some time ago and we had few problems since. Only moving to the newest version of bundler made some noise. The rest was just great.

  • XSS A change under the hood. Rails 3 will escape all output, the developer has to explicitly state what not to escape. Until now it was the other way around. This small plugin (http://github.com/nzkoz/rails_xss ) and a switch from erb to erubis (erubis is also faster, by the way) made this very simple

  • UJS Why should you spend time writing rjs or doing all jQuery AJAX by hand? We eagerly waited for the jquery-ujs javascript code and now finally it is out. This is just perfect, download it, add it to your project and start writing nice new mark-up and everything works better. In Rails3 the linkto and formfor helper will even generate the markup, but that is the minor part of the change. The important step is: no rjs anymore and better jquery-ajax code. Great.

These are great new developments and it is easy to use them right now in your project. Just do it.

The other features we are still waiting for:

  • new routing
  • complete rack support
  • a plugin API
  • active model and new active record
  • a more complete i18n support
  • new railties, especially better rails engines support and system events
  • no more aliasmethodchain, instead module, mixin and classes .. why and why2 ... this just makes so much more sense...

a very good overview about all new features and changes by ryan daigle .. from edgerails.info

MySQL BEFORE INSERT trigger as check constraint

Since MySQL does neither have real check constraints nor a way to raise an exception in a stored procedure, we found it not instantly obvious, how we could reject a certain row on insert, based on a certain condition.

A nice way we found was to set the value in question to NULL, based on the condition and let the NOT NULL constraint do its work.

ALTER TABLE some_table MODIFY some_id varchar(255) NOT NULL;
DROP TRIGGER IF EXISTS check_someid;
DELIMITER $$
CREATE TRIGGER check_someid BEFORE INSERT ON some_table  
FOR EACH ROW BEGIN
  IF NOT NEW.some_id REGEXP '^[[:xdigit:]]{32}$' THEN
    SET NEW.some_id = NULL;
  END IF;
END;
$$
DELIMITER ;

The trigger will let any 32 character string with only HEX characters for the column some_id pass and rejects the rest.

> INSERT INTO some_table (some_id) VALUES ('ffffffffffffffffffffffffffffffff');
Query OK, 1 row affected (0.01 sec)

> INSERT INTO some_table (some_id) VALUES ('fffffffffffffffffffffffffffffffg');
ERROR 1048 (23000): Column 'some_id' cannot be null

Happy triggering.

Work work-flowing

Bram Moolenaar gives very good advices on how to improve the text-editing workflow.

Essentially it is about improving your workflow in small steps:

  • Start reflecting what you are doing not as efficient as you would like to, over and over again.
  • Then find a way to improve it, take the time to find a solution.
  • Make it a habit, then start again reflecting.

I created some habits while working with Rails, which are simple and small

Aliases:

 sc - script/console
 ss - script/server 
 gst - git status

small functions in bash

restart passenger:

function res {
  echo "restarting passenger"
  touch tmp/restart.txt
}

run parallel specs:

function pspec {
  echo "specing"
  rake parallel:spec[2]
}

These are my favorites right now. The important thing is not the functions themselves, but the habits. I use them over and over again. I cannot work without them anymore.

Another automation, a bit off-topic

In my spare time, I listen to a whole slew of netcasts. When I am at home, I listen to these on my Crapbook, so I can use a handly little piece of Applescript whipped up by Randal Schwartz that passes the current track from iTunes to QuickTime, adjusting the playback speed to 1.5 times the normal speed.

I found netcasts to be a very pleasant distraction from the horrible music usually played at the gym. Unfortunately my portable MP3 player doesn't let me adjust the playback speed, so I need to adjust it in the MP3 files themselves. The following script does just that.

require 'rubygems'
require 'rbosa'

RATIO = 1.5
target_dir = "/tmp/#{$0}/#{Time.now}"
`mkdir -p "#{target_dir}"`
iTunes = OSA.app('iTunes')
iTunes.selection.each {|track| `cp "#{track.location}" "#{target_dir}"`}
%x(
  cd "#{target_dir}"
  for f in *
  do sox -t mp3 "$f" "$f.wav" tempo #{RATIO}
  lame "$f.wav" "$f@#{RATIO}.mp3"
  rm "$f" "$f.wav"
  done
  open .
)

First I select the tracks I want to convert in iTunes, then I invoke this script. When applied to 10 or more tracks, the processing done by sox and lame can easily take a few minutes, so I added the call to open ., which opens a Finder window with the converted files as soon as everything is done, so I can grab them and move them to my MP3 player.

Automation of the week: fetchr

When a program tells me that there is a new version available, I usually get that new version and put it on a shared directory on our file server, so anyone else can take it from there, enjoy a quicker install and save some precious bandwidth. Recently I fired up VirtualBox on a box that I didn't use for a while, so it complained about being outdated.

What bugs me about these situations is that downloading a package like VirtualBox takes a few minutes and that's, at least in my opinion, a pretty annoying time span. It's not enough to reasonably do anything else, but enough to think about how to get rid of these breaks. This time I used these few minutes to come up with an idea, which resulted in the following piece of Ruby.

require 'open-uri'

TARGET = '/some/place/to/store/the/files'
packages = {
  :virtual_box => lambda do
    latest = open('http://download.virtualbox.org/virtualbox/LATEST.TXT').read.chomp
    index = open("http://download.virtualbox.org/virtualbox/#{latest}").read
    index.
      scan(/VirtualBox.+?OSX.dmg|virtualbox.+?Ubuntu_jaunty_i386.deb/).
      uniq.select {|filename| !File.exists? "#{TARGET}/#{filename}"}.
      map {|filename| "http://download.virtualbox.org/virtualbox/#{latest}/#{filename}"}
  end,
  :firefox => lambda do
    %w(mac win32).map do |platform|
      %w(2.0 3.0 3.5).map do |series|
        index = `lynx -dump ftp://ftp.mozilla.org/pub/firefox/releases/latest-#{series}/#{platform}/en-US/`
        index.
          scan(/Firefox .+?(?:exe|dmg)/).
          uniq.select {|filename| !File.exists? "#{TARGET}/#{filename}"}.
          map {|filename| "ftp://ftp.mozilla.org/pub/firefox/releases/latest-#{series}/#{platform}/en-US/#{filename}"}
      end
    end.flatten
  end
}

packages.each do |name, url_fetcher|
  puts "fetching urls for '#{name}'"
  url_fetcher.call.each do |url|
    `wget -P #{TARGET} '#{url}'`
  end
end

Writing the code to fetch VirtualBox was too easy to stop there, so I added a block for Firefox. mozilla.org didn't respond to open, so I lynxed instead. I put this script on our file server, pointed TARGET to the directory we usually put setup files in and created a cronjob to run it once every night. So whenever I need the latest version of VirtualBox or Firefox, there's a good chance it's already in local network range.

Authlogic: logged_in? depends on last_request_at

Authlogic, a popular authentication plugin for RoR, has its share of magic, some well documented, some less.

One thing that kept me busy yesterday was the absence of the logged_in? method on instances of the User class. Turns out, authlogic, again, adapts its abilities depending on which columns the users table has. For the logged_in? method to exist, the column last_request_at must exist.

Now in the code there is a little bit of confusion, because in the authlogic lib file logged_in_status.rb there are actually two places dealing with this dependency:

def logged_in?
  raise "Can not determine the records login state because\ 
  there is no last_request_at column" if !respond_to?(:last_request_at)

  !last_request_at.nil? && last_request_at > logged_in_timeout.seconds.ago
end

The exception should have brought me onto the right track, but, as it turns out, the instance methods themselves are only included, if the column last_logged_in exists, see the line

return if !klass.column_names.include?("last_request_at")

of the same file. So there you have it: no exception, just a silent absence of the method logged_in?.

Happy authenticating!

Passion, Communication and Professionalism

I just updated our job description. After we announced our job offer we got some really good feedback. I talked to some Ruby Developers and i realized what i good developer toolbox should be:

Passion.

The be better then our competitors, to reach our goals, to grow and learn, we need passion.

Professionalism / Rationalism

Professionalism is the needed power to balance passion. Just passion can be blind and wrong used. Programmers like to dig a whole into the ground and loose their mind in it. That’s what people call hunting a bug or fixing a problem. But it sounds not good to me. Passion turns into possession.

Communication

The third important ability is communication. If i don’t get the feeling i can communicate open and directly to a person, how can i trust a person? We are a growing team, with passionate and very different personalities. To work and learn successfully as a team together, we need to be able to understand each other, to jump the gap between us.

This is a big topic and i am just at the surface of it. Hopefully better then nothing. Comments are very appreciated!!

Give javascript some love

I am reading the nice titled book “javascript – the good parts” and i guess most people needed a long time, like me, to understand what javascript is. Maybe this is the reason why so many javascript-code is a hack. Spaghetti tastes good, but…

We are using jquery as our js-libary and a “normal” bit a javascript code looks like this:

jQuery(document).ready(function() {
    $("#same_id").click(function(){
        action1
        action2
    });
    $("#another_id").click(function(){
        action3
    });
});

i think nobody would ever do this in a “real” programming language. Why not make it expressive and structure it a bit?

var Homepage = {
   init: function(){
      $("#same_id").click(Homepage.doA)
      $("#same_id").click(Homepage.doB)
   },
   doA: function(){
      action1
      action2
   },
   doB: function(){
      action3
   }
}
jQuery(document).ready(function() {
  Homepage.init()
});

What do you think?

P.S. This code is probably not 100% valid :-)

Scrum and Web Hooks

Earlier this evening I joined the gathering around Ken Schwaber and listened to his both interesting and entertaining anecdotes. One of my favorites was about a manager who had just beed introduced to the concept of Scrum. He was enlightened by the idea, yet he demonstrated that he didn’t really get the point by asking how he could make sure that his team was actually doing Scrum right and that he would probably have to go over to the team and check if everyone was on the path of Scrum.

That anecdote somehow reminded me of what I read and heard about Web Hooks. Instead of polling every n seconds if some data is available yet/asking the developers if a feature is ready, you should rely on the application you are waiting for to inform you about data being available/rely on the developers telling you when they are done. Not only does this prevent management from draining precious time from developers, it also removes a very tedious task from their list and therefore even gives them some more spare time for doing something really useful.

In this spirit: Web Hooks and Scrum for the win!

( Here is more about the scrum master meeting on Tim’s blog )

We are hiring - updated!

Just a short note, a reminder, we still are looking for good ruby developers for all the cool stuff to come out of our engineering rooms. You can find more details on our job page

Who will create the portable device platform of the future?

What happened to Microsoft, do they have a 100.000 sleeping software developers without any imagination ? Yes, everybody is smarter if you can look back.

After i watched the presentation of the new iphone 3.0 version, i understood that the iphone started as a nice, well done phone, but they have the real potential to make it the portable device platform. I don’t think it will become market dominant, it is to expensive and too closed. All the old Mobile-Phone producer are excluded.

I just hope there won’t be any monopole like we still see it in the pc-market.

Workshop week is over

I wrote this one on the way back to Berlin and forgot to actually post it in the evening and didn't have my Macbook in the office, so with some delay, here's the last post about the first workshop week.


We are on our way back to Berlin and as far as I am concerned, I consider the last week to be a great success.

What did we do? First, we set up some realistic goals. Then, we started working on these goals in short iterations, talking about our progress usually three times a day with all participants in place, mostly during meals or while preparing them. There was a lot of communication going on this week, and it was efficient. No phones riniging, no people bursting into the office bothering us with questions.

I can't say I really learned anything new during this week. I was convinced that this kind of work is very efficient for certain tasks, but it was the first time we actually tried it. It was rather an affirmative experience, seeing that leaving the regular office to work somewhere else with a small team and on a well-defined task, actually can result in boosted productivity, as long as people want it to. I hope this will not be the last endeavour of this kind at jovoto.

As a small reminder of this week, here's a photo of the team.

News from the front

Last Saturday Guido , Arturo and Daniel (aka me) hit the road , heading towards Westerwald. It took about 8 hours and when they arrived, they were all pretty hungry, so they had to buy some food . The next day they made themselves a nice dish they, of course, ate outside, sitting in the sun. Tim, who wasn't mentioned before, because the images in this post have to be used in order of recording for some reason, was very pleased. . End of blog post.

O du schöner Westerwald

That’s where I come from. And that’s where we are going.

In April the majority of jovoto’s technical staff will spend a week in the lovely countryside in which I grew up. We take the chance of escaping the office in order to work highly focussed on a specific task in an inspiring environment. As this is the first time we are doing something like that, it’s somewhat of an experiment. I am confident and convinced that this will be a fulfilling endeavour for all participants, though.

In case someone doesn’t know what Westerwald is all about, what it looks like there and what people usually do there, here’s a small foretaste.

it's getting hot! treetonin now with node temperature

I just added a feature to treetonin and it’s called node temperature. It is inspired by the PageTemperature plugin for the Kwiki wiki. About a year ago I was about to start a private project with two co-workers. We had some good ideas but not enough time to finally get it going.

While setting up the infrastructure for this project I discovered Kwiki, a highly modularized wiki that was installable entirely through CPAN. CPAN is obviously not a code hosting solution for everyone, as it is the place for all things Perl (and some C/C++ for XS modules), so you can’t really compare it to Github. But the approach of publishing a system as a set of individual modules bears some similarities to Rails apps that are in essence glue code to combine gems and plugins, each of which can be obtained from Github.

Enough talking. Here’s a screenshot of the current status of the awesome treetonin project with the node temperature feature already baked in.

This first version the feature just translates the age of the node to shades of red by calculating ((current – oldest) / (latest – oldest)) * 255 and using the result as the red component. Both green and blue remain 0, so I scale from black to shiny red. Future versions might evaluate the number of updates and visualize it as font size, or the amount of data stored as border thickness, or something completely different.