“...I've been working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix and learning Rust. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working for InPay...”

Rob Lacey
Senior Software Engineer, UK

ActiveRecord::MultiparameterAssignmentErrors

interesting bug, ever heard of this one ActiveRecord::MultiparameterAssignmentErrors?

So, on your social networking site the person signing up want’s to expose their birthday so they can get loads of best wishes but is a bit conscious of their age.

>> Person.new("born_on(1i)" => "", "born_on(2i)" => "4", "born_on(3i)" => "25")
ActiveRecord::MultiparameterAssignmentErrors: 1 error(s) on assignment of multiparameter attributes

This has only occured ocassionally, not everytime someone doesn’t want to set their year of birth.

born_on(1i) : year
born_on(2i) : month
born_on(3i) : day

>> Person.new('born_on(1i)' => '2012', 'born_on(2i)' => '12', 'born_on(3i)' => '12').born_on
=> Wed, 12 Dec 2012
>> Person.new('born_on(1i)' => '', 'born_on(2i)' => '12', 'born_on(3i)' => '12').born_on
=> Thu, 01 Dec 0012

It turns out the assignment gets really confused when it is nil, or at least when the first interger is nil it removes it and sets the first integer it finds to the year, the second to the month and the third…well it sets it to 1, or the first of the month. How annoying. I would have hoped you could validate against assigning incomplete dates, but apparently not.

This breakdown from Thoughtbot demonstrates the process they took to not really solve this problem. Ultimately they used a work around; a before_filter in the controller.

http://robots.thoughtbot.com/post/159808527/ruby-on-fails

def validate_expires_on
    Date.new params[:job]['expires_on(1i)'].to_i,
    params[:job]['expires_on(2i)'].to_i,
    params[:job]['expires_on(3i)'].to_i
  rescue ArgumentError
    params[:job].delete 'expires_on(1i)'
    params[:job].delete 'expires_on(2i)'
    params[:job].delete 'expires_on(3i)'
  end

I guess a before_filter that matches all (i) params could be put in an application wide before_filter to cover every case like this, if arises.

Skype doesn't work in Karmic Koala

I had to uninstall the Jaunty package from Multiverse…

apt-get remove skype skype-common

…and then re-install the 8.10+ version from Skype. You may need to restart pulseaudio and mute and un-mute the microphone it working again.

dpkg -i http://www.skype.com/go/getskype-linux-beta-ubuntu-64

http://friendlytechninja.vndv.com/2009/10/16/howto-install-skype-on-ubuntu-9-10-karmic-koala/

Karmic Koala doesn't actually add the kernel to menu.lst

I had sever issues this morning after last night’s upgrade from Ubuntu Jaunty to Koala. Xorg was constantly at 98%, sound was broken, and the whole system was completely unresponsive.

Looking in /boot/grub/menu.lst I noticed the upgrade hadn’t actually added the new kernel at all. So I copied to config for the previous kernel and updated it to the new 2.6.31-14 kernel and on reboot we have sound and Xorg is now playing nicely at about 2% CPU. Panic over.

title   Ubuntu 9.10, kernel 2.6.31-14-generic
root    (hd0,0)
kernel    /boot/vmlinuz-2.6.31-14-generic root=UUID=a3c5e83c-f5f2-4704-8bd9-530ecf71f9e5 ro quiet splash acpi_osi="Linux"
initrd    /boot/initrd.img-2.6.31-14-generic
quiet

title   Ubuntu 9.04, kernel 2.6.28-11-generic
root    (hd0,0)
kernel    /boot/vmlinuz-2.6.28-11-generic root=UUID=a3c5e83c-f5f2-4704-8bd9-530ecf71f9e5 ro quiet splash acpi_osi="Linux"
initrd    /boot/initrd.img-2.6.28-11-generic
quiet

HR Giger Ibanez

I saw this about a year ago, it doesn’t have 7 strings….but its the most gorgeous piece of electromological greatness I’ve seen in a while. I guess the only issue is that I wouldn’t want to ruin a work of art by actually playing it.

Shirts and Destroy

My favourite independant T-Shirt manufacturer and store, Shirts and Destroy have two new Agoraphobic Nosebleed shirts in stock.

Just a quick quote from their site…

The profits for the items you buy here go to the Bands and Artists we work with. So you really are SUPPORTING these bands and artists when you shop with us. We strictly work with people who’s art we respect and admire. Nothing is sold here that we don’t stand behind artistically 100%. If something offends you were not sorry… this isn’t the mall. Thanks for helping us do our part in supporting independent art and music.

Basically, they rock! Help support the bands you love.

High Heels From Hell Vs The Undead

Really liking this one…

Stubbing out live calls to via Facebooker

I just can’t find a way to stub out Facebooker::Service, this just didn’t seem to work.

fs = mock_model(Facebooker::Service, :post => "1")
Facebooker::Service.stub!(:new).and_return(fs)

So finally I used.

describe FacebookPublisher do

  class Facebooker::Service
    def post(*args)
      return "1"
    end
  end

  it "just should ok" do
    Facebooker::Session.create.<some method thingy>
  end

end

ActionMailer with ActiveRecord validation

I wanted to be able to send out a mail from a controller but also validate the incoming args in a clean way. Like so…

class MessagesController < ActionController::Base

def deliver
  @message = Message.build(params[:message])
  if @message.deliver
    redirect_to home_path
  else
    render :action
  end
end

ActionMailer::Base hides the initialize methods in method_missing and most of the time you are calling ActionMailer::Base.deliver_mymail(args). This allows you to specify all of the standard actionmailer settings in Message.build and return a Message object.

class Message < ActionMailer::Base

  include Validatable
  validates_presence_of :from, :body

  def self.build(args = {})
    new('default', args)
  end

  def self.action_mailer_methods
    return [
      :bcc,
      :body,
      :cc,
      :charset,
      :content_type,
      :from,
      :reply_to,
      :headers,
      :implicit_parts_order,
      :mime_version,
      :recipients,
      :sent_on,
      :subject,
      :template
    ]
  end

  def default(args)
    new_args = args.clone
    new_args.each do |k,v|
      if self.class.action_mailer_methods.include?(k)
        send(k, new_args.delete(k))
      end
    end

    if body.kind_of?(Hash)
      @body.merge!(new_args)
    end

  end

  def deliver
    if self.valid?
      return deliver!
    else
      return false
    end
  end

end

Pandora console

The Pandora

…the most powerful gaming handheld there is….

  • ARM® Cortexâ„¢-A8 600Mhz+ CPU running Linux
  • 430-MHz TMS320C64x+â„¢ DSP Core
  • PowerVR SGX OpenGL 2.0 ES compliant 3D hardware
  • 800×480 4.3" 16.7 million colours touchscreen LCD
  • Wifi 802.11b/g, Bluetooth & High Speed USB 2.0 Host
  • Dual SDHC card slots & SVideo TV output
  • Dual Analogue and Digital gaming controls
  • 43 button QWERTY and numeric keypad
  • Around 10+ Hours battery life

Now, I’ll need some more freelance work to get my hands on one of these.

Oooh....erb templates in javascript

Found this ERB for jQuery script this morning from Dan Webb

http://gist.github.com/211964

// ERB style templates for jQuery in hardly any code.
//
// Based on http://ejohn.org/blog/javascript-micro-templating/
// 
// A tiny and simple plugin to allow erb style template rendering within jQuery.
// 
// Make a template:
// 
// <script type="text/html" id="template1">
// <% $.each(items, function(i, image) { %>
//   <p><img src="<%= image.media.m %>" alt="<%= image.title %>"></p>
// <% }); %>
// </script>
// 
// Render the template into the dom with some data:
// 
// <script type="text/javascript">
// jQuery(function($) {
//   $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=jordan%20III&format=json&jsoncallback=?", function(data) {
//     $('#test').render('template1', data);
//   });
// });
// </script>
//
// Alternatively, you can load templates from files:
//
// $('#test').render('template.ejs', data);

jQuery(function($) {
  var cache = {};
  
  function compile(source) {
    return new Function("obj",
          "var p=[],print=function(){p.push.apply(p,arguments);};" +
     
          "with(obj){p.push('" +
     
          source
            .replace(/[\r\t\n]/g, " ")
            .split("<%").join("\t")
            .replace(/((^|%>)[^\t]*)'/g, "$1\r")
            .replace(/\t=(.*?)%>/g, "',$1,'")
            .split("\t").join("');")
            .split("%>").join("p.push('")
            .split("\r").join("\\'")
        + "');}return p.join('');");
  }
  
  function load(template) {
    if (!(/\W/).test(template)) {
      return compile($("#" + template).html());
    } else {
      var source;
    
      $.ajax({
        async: false,
        url: template,
        dataType: 'text',
        success: function(data) {
          source = data;
        }
      });
    
      return compile(source);
    }
  }
  
  $.template = function(template, data) {
    var fn = cache[template] = cache[template] || load(template);
    
    if (data) return fn(data);
  }
  
  $.fn.render = function(str, data) {
    return this.each(function() {
      $(this).html($.template(str, data));
    });
  };
});
GPK of the Day Mean GENE