‘belongs_to’ and ‘has_one’ Differentiated

One of the more common confusions with ActiveRecord associations is the difference between the `has_one` and `belongs_to` relationships.

However, they are not interchangeable, and there are some serious differences. A `belongs_to` can only go in the class that holds the foreign key whereas `has_one` means that there is a foreign key in another table that references this class. So `has_one` can only go in a class that is referenced by a column in another table.

So this is wrong:

class Transaction < ActiveRecord::Base
  # The transactions table has a order_id  
  has_one :order                
end

class Order < ActiveRecord::Base
  # The orders table has a transaction_id
  has_one :transaction          
end

So is this:

class Transaction < ActiveRecord::Base
  # The transactions table has a order_id
  belongs_to :order             
end

class Order < ActiveRecord::Base
  # The orders table has a transaction_id
  belongs_to :transaction     
end

For a two-way association, you need one of each, and they have to go in the right class. Even for a one-way association, it matters which one you use, and which direction you use it:

class Transaction < ActiveRecord::Base
  # This table has no foreign keys
  has_one :order             
end

class Order < ActiveRecord::Base
  # The orders table has a transaction_id
  belongs_to :transaction     
end

How to Create a Bootable Lion Restore USB Drive without Snow Leopard

If you are like me and have installed Mac OSX Lion on a computer and need or want to create a bootable OSX Lion USB Drive, Apple have released an official tool to accommodate you.

Its pretty basic, download the tool, run the file inside the .dmg file and follow the prompts. You will need a 8Gb USB thumb drive (I believe 4GB won’t quite be enough). Now you can simply plug the thumb drive in, and on boot hold down the [option] key and select the recovery drive from the menu. I can verify that you can use this installer to create clean installs of lion without having to first install Snow Leopard and on machines other than the one that created the recovery drive.

System-wide Git Global Ignores

If you are like me and love using a Mac for your development tasks, and want a way to get Git to ignore any file (like those pesky .ds_store’s) forever and for EVERY repository there is a very simple way to it.

Open Terminal and type:

git config --global core.excludesfile ~/.gitignore

and then:

echo .DS_Store >> ~/.gitignore

This will work for anything you want, just modify the second command as appropriate.  And you can run the second command as many times as you need.

Ruby Script to Import Google Contact Photos From Gravatar

Google Contact photos are a much neglected feature of the Google Stack. It really adds to the user experience when you see each of your contact photos when you make or receive a call. However, it can be a real pain (especially if you have hundreds of contacts).

But I had an idea recently, to try and match my Google Contact emails with Gravatar and try to auto-populate some of the dozens of contacts that didn’t already have a photo (after all a Gravatar is better than nothing).

So I wrote a Ruby script to find my contacts missing a photo and try to update it with a Gravatar (wherever possible). NB: You may need to first install the GData (Google Data) gem by opening a Terminal window and issuing: sudo gem install gdata.

#!/usr/bin/env ruby

# Google Contact Photos - Gravatar Importer
# Written by Ashley Angell
# http://ashleyangell.com
# Licenced under Creative Commons with Attribution

require "rubygems"
require "gdata"
require "rexml/document"
require "digest/md5"
require "net/http"
include REXML

none = 'd5fe5cbcc31cff5f8ac010db72eb000c'
user = ARGV[0]
pass = ARGV[1]

client = GData::Client::Contacts.new
client.clientlogin(user, pass)
data = client.get("https://www.google.com/m8/feeds/contacts/#{user}/full?max-results=10000")
myxml = Document.new data.body
p "contacts"
puts "-"*70
i = 0
myxml.each_element("feed/entry") do |e|
  begin
    gd = e.elements['gd:email']
    if !gd.nil?
      email = gd.attributes['address'].downcase
      hash = Digest::MD5.hexdigest(email)
      image_src = "http://www.gravatar.com/avatar/#{hash}"
      nil_image = false
      image_element = e.get_elements("link[@rel='http://schemas.google.com/contacts/2008/rel#photo']")[0]
      if !image_element.nil? and image_element.attributes['gd:etag'].nil?
        data = nil
        md5 = nil
        Net::HTTP.start(URI.parse(image_src).host) do |http|
          resp = http.get(URI.parse(image_src).path)
          data = resp.body
          md5 = Digest::MD5.hexdigest(data)
          File.open("#{email}.png", 'w') do |f|
            f.puts data if md5 != none
          end
        end
        md5 = Digest::MD5.hexdigest(data)
        if md5 != none
          puts "#{email} > #{image_src}"
          client.put_file(image_element.attributes['href'], "#{email}.png", 'image/png')
          i = i + 1
        else
          puts "#{email} > no match"
        end
      else
        puts "#{email} > skipped (already has photo)"
      end
      File.delete("#{email}.png") if File.exists?("#{email}.png")
    end
  rescue Exception => ex
    puts ex
  end
end
puts "Updated #{i} contact photos"

To execute it, simply copy and paste this into a text editor (or download it and unzip) and from Terminal (command) window and execute the following commands:

sudo chmod +x googlegravatarimporter.rb [Enter]
./googlegravatarer.rb your.address@gmail.com your_password [Enter]

It will cycle through your Google Contacts and indicate what action was taken. For me, surprisingly updated a few dozen contacts (even more than I expected).

I’ve posted this here for others that might want to do the same thing but cannot be bothered writing the script for it. Consider it posted here under Creative Commons with Attribution.

Convert SQL Server Database to a SQLite Database

Recently, I wanted to resurrect an old project of mine I worked on in my spare time originally designed to work on .Net technologies. Naturally, I backed it against a SQL Server 2005 Database which turned out to be a bad idea because it made portability of that data a bit of a nightmare.

So it was with great happiness that I found this tool (mirrored here) by liron.levi who posted an article on CodeProject on how to accomplish this task. You still need a Windows machine and an install of SQL Server (Express Edition with Advanced Tools is alright) but it got the job done just fine for me.

If you want a no-fuss easy way to convert your databases into a format easier to deal with and a lot more portable to-boot.

How to Boot Toshiba Portege M200 off an SD Memory Card

A long while ago I became the proud owner of one o the best Tablet PCs on the market, the Toshiba Portege M200. Problem is that if something goes awry on the internal hard disk, then you’re in trouble because the M200 is notoriously difficult to boot on external media. This was something I needed to do after trying out Windows 7 on it (which worked extremely well by the way) – but it came at a cost too high – missing features and tools and drivers that the default factory install has.

Things are made complex because while it is technically possible to boot off an external CD/DVD ROM, the number of external drive it will actually boot off are very few. Additionally, the BIOS wont boot off USB thumb drives (at all!) and USB hard disks either. There is one saving grace – you can boot off an SD memory card (as long as it *not* SDHC) from the built-in reader. The trouble with THIS is that it will only boot off an SD card if its been formatted and made bootable ‘just right’. Its so finiky that Toshiba have actually created some tools to aide in the process of making them bootable.

So, if you have a standard SD memory card, you can use the Toshiba SD Memory Format Utility and the Toshiba SD Memory Boot Utility to create a bootable image of the restore CDs. Obviously if the default install is bung, then how can you use these tools?

Well the good news is, I’ve got a copy of them from the Toshiba website. I have hosted them here in case they disappear, here is the Toshiba SD Memory Format Utility and here is the Toshiba SD Memory Boot Utility.

What I did to reinstall the factory image on my Portege M200 Tablet PC:

  1. Download the 2 links above and install them.
  2. Run ‘as administrator’ (if on Vista or Windows 7) the format utility and format the SD card.
  3. Run ‘as administrator’ (if on Vista or Windows 7) the boot utility and select the BOOT.IMG file from the /bin folder on the first restore CD. Here is a copy if you don’t have the disks.
  4. Restart the computer pressing F2 at POST and with the SD card in the reader, and use the arrows keys to select the SD/Floppy boot device.  Press [Enter].

When I booted it still gave me the CD ROM selection screen, which I eventually discovered was actually compatible with the External USB DVD ROM I was using (wouldn’t boot off it – but option ‘9’ worked in DOS) – after this, it just started installing the factory image as normal.

Any problems, drop me a line and I will try to help.  I know how frustrating this can be after spending most of the day trying Linux boot disks and direct copying boot sectors etc.  Ahh! but finally success!

 

‘File not found: lib’ Error installing Rails Gem

I recently had a problem trying to install Rails 3 on my MacBook with a fresh OSX Snow Leopard:

sudo gem install rails
Password: {entered}
Successfully installed rails-3.0.7
1 gem installed
Installing ri documentation for rails-3.0.7...
File not found: lib

Turns out this is a somewhat common problem.  But it seems that the solution is easy, just manually reinstall RDoc. To do this run these 3 commands:

sudo gem install rdoc-data
sudo rdoc-data --install
sudo gem rdoc --all --overwrite

The last line in particular will re-generate all the documentation for your installed gems (including Rails) and can take a while, but you should be able to confirm the fix by reissuing the Rails gem install command:

sudo gem install rails

shows that rails now installs properly and says that it has installed both ri and RDoc documentation without issue.

FeedBurner

I’ve had a FeedBurner account for a long time.  Why hav’nt I used it? I dunno.  So here marks the start of a beautiful relationship (I hope).

It turns out ‘Eat-Less’ & ‘Do More’ Isn’t Enough! (for me)

I’ve always considered myself to be a practical and rational person. Dieting was a simple equation of energy in and energy out. But based on the past 9 months, I have to say that its just not that simple, especially people who like me have been considerably overweight for a long time.

My significant weight-gain started over 11 years ago.  While I don’t hold her accountable, its true that my pregnant teenage girlfriend (who I married a year later) peer-pressured me into eating much larger meal portions than I should have.  At the time I blamed this over eating on her need to feel better with her own weight, but the truth is that I ate it because it was in front of me and most of all, because I wanted too.

The gain was gradual at first…so gradual in fact that it wasn’t until I saw myself in our wedding photos that I noticed at all.  I hated what I saw in myself from those photos, but after many years of consideration I wonder if I subconsciously knew in my heart that I looked fat.  I wonder if that was the reason I prioritized the importance and the significance of our wedding photos (which turned out terrible due to poor lighting control and poor quality cameras – something I regret to this day).

But the fact remains that I ate when I was hungry, I ate when I was happy, I ate when I was sad, I ate when I was bored, I ate in company – I medicated myself with food.  Food never judges you, and at least in the moment, food is a powerful mood elevator.

I also never found comfort in exercise. People all my life would often talk about how they get the endorphins and “good feeling” that comes after exercise. I very much believe that some people don’t get this. I think this because I am one of them.  All my life, regardless of how much exercise I endured I never got any feeling other than hot, sweaty, tiredness.

Additionally, over the past couple of years I’ve battled diagnosed depression. Clearly, despite the growing disconcerted feelings inside about my body image, I wasn’t in a place that was conducive to weight loss. Those years were one of survival (and getting better) – not about vanity.

But 9 months ago I reached critical moment in my life. My darling wife and I were shopping for a new suite for me to wear at her 30th birthday party and after failure after failure in several various department stores to find a suite in my size, one of the sales assistants asked me (as delicately as she could) “I think perhaps you might have more luck at a store for ‘larger men'”. I don’t begrudge the assistant, because from the shaky delivery it was clear that she was extremely uncomfortable suggesting it and just trying to help however she could.  But those words echoed in my mind and tore at my very soul. It destroyed whatever self-respect and dignity I had left. I forced myself to shutdown all my feelings and emotions because the pain was so severe. I wanted to fall about. My wife, clearly saw that I was in extreme distress, but all I could do was make some vague hand gestures and walk around the mall, trying to focus on something, anything except the echo of the words: “you’re so fat you’re not even worth making clothes for” echoing in my mind. I remember forbidding my mouth to speak, because I knew that doing anything except focusing on holding myself together was going to cause a complete breakdown. My wife, feeling my pain tried to calm me. It didn’t help at the time, but it helps me now to remember how much she cares for me (and it makes me warm and fuzzy inside to think of it).

I have never felt, like that before. Not even during my depression years. In hindsight, it’s not entirely impossible that it in fact, was some kind of temporary relapse.

I eventually did find some courage in the tank, and having been completely robbed of any hope and completely defeated, my wife suggested we try “Roger David’s” on our way back to the car.  I was convinced it was a waste of time, but defeated people with no self-respect tend to go with the flow, so I said “ok”. As it had it, at 5 minutes to close we discovered that they did have a suite in my size (barely). This moderately improved my melancholy.  They put it on, measured me for the tailoring to make it fit better and we paid and left for home.

A couple of days later when I went to retrieve the suite after its alterations were complete, I was faced with the demons of the previous visit. Needing a coffee to bolster my confidence (and silence the pain) I entered the Border’s bookstore and grabbed one. On the way out of the store, standing quite prominent near the entrance was the “Dukan Diet” book. I’d never heard of it before, so I picked it up and had a flip though. I read some of the summary pages and the way it was written (pseudo-scientifically) really resonated with me. I proudly bought it home to @MrsAngell declaring my intentions to embark on the journey it described. There is something intoxicating and powerful about taking charge of your life.

Initially she was unconvinced and actually quite negative towards it and it quickly erupted into an argument. During the argument I pointed out that she hadn’t read the book yet a point she conceded. I also explained that I needed to do this to claw back the self-respect I so badly lost. That night we read a chunk of the book together and having been convinced by it, we elected a time to start it, together.

It’s been hard, and while my journey still continues, her’s is all but complete. She’s lost 25kg and I’ve lost just under 30kg (so far). I still don’t think that I look much better (believe it or not) but I hope the vanity will kick-in, in another 20 or so kg. My goal weight is somewhere under 80kg. A weight I haven’t been since the year our first child was conceived, 11 years ago.

And to be honest, vanity is what it’s all about. I don’t think that vanity should be demonized the way that it is. A number of weight loss friends, have all mentioned to me how family in particular trivialize their weight loss goals, and even on occasion directly sabotage it. Weight loss is hard enough without the people you love destabilizing your lifestyle changes. Naturally they don’t mean to, but since they love you unconditionally and aren’t attracted to you, they’re hardly objective folk. Friends are mostly supportive, but I have to say that this would have been impossible without the help, love and support of my dear Mrs Angell.

In sum it’s clear that weight loss is not simple as most people believe. There are layers and complexities so deep and contradictions so entrenched that it’s becoming harder and harder to differentiate the fact from fiction. Despite it’s recent popularity (especially in Hollywood) it’s easy to trivialize Dukan as being a fad diet – but as someone who has been on it for nearly a year, I can say that isn’t the case here. In the three people close to me who have embarked on it (and stayed on it) its got a 100% success rate, and so far, they’ve held a constant weight after it. I’ve also discussed the diet with my GP and had 3 general checkups, 2 broad spectrum blood tests performed and given blood 3 times since being on this diet (one of them on day 0 of the diet as a control). I was in general good health prior to the diet (all measurable indicators within acceptable margins) but now my GP describes me as being in textbook perfect health. This diet is not something I did with whimsical triviality. I was cautious, calculated and scientific with it. I had some bad days (some of them several in a row) but for the most part I was true to the Dukan Diet. Birthdays, Christmas and Easter were basically “write-offs” and I blame these (and my own lack of self-control) for the plateau I’ve experienced over the past few months.

However, its not the only way to loose weight – its just what works best for me. My very dear Sister-in-law just reached her goal weight (horray!) recently using a diet prescribed by her personal trainer. I must admit that sometimes I found myself frustrated on her behalf on her bad/stagnant weeks and I tried as best as I could to help, motive and support her on her personal journey. I can say that she’s done an outstanding job on the same, for me. Honestly, without her and her sister; I don’t think I could have gotten this far. However, while I am happy for her, I am also selfishly saddened because now I am about to embark the second half of my weight loss on my own. The journey is long and lonely on your own. I know they will still support me, but they’re no longer in the game; and that makes a difference. I try to reassure myself that I haven’t failed in not reaching my goal weight yet, but rather, that I’ve got 3 times as much to shift as they did.  But I will do it.  I have to.

I am now happy to discuss weight and diets with people now. Something I always felt awkward about before. But the one constant and most important fact I’ve learned is that when it comes to weight loss, its more complicated than ‘Eat-Less’ & ‘Do More’.

AirPush is Offensive to my Sensibilities

I saw this tweet from a friend (@RyanBooker) today: “Is this for real? This would guarantee your software is immediately uninstalled” with a link to the following video:

And I don’t know about you but it really gave me the heebie-jeebies. I found myself being repulsed in illogical, unreasonable ways. I’m not even an Android developer (or user), but I found this completely offensive. After I cooled down and was able to think clearly for a minute I reflected on why I had such an adverse reaction. I realized that its all about the sacredness of notifications.

You see we are slowly migrating over to a post-scarcity world. Information, is one commodity which has become so abundant (and so cheap); that it’s become a limitless resource. In a post-scarce world, the main commodity is attention. User attention becomes the focus of generating profits and this is (and has always been) the entire idea behind advertising. Advertisers pay others for a slice of the attention they receive.

As user’s expose themselves to greater quantities of new information and media, they spend greater quantities of their focus (and attention). Sooner or later, unless users can adopt greater efficiencies their attention becomes very scarce. I think we’ve reached a point where our collective attention is so scarce as to it being entirely depleted. We’re so saturated with new media and access to information that the effectiveness of advertising is becoming greatly diminished. We’ve become desperate to find “a few more minutes in a day” and thus we’ve adapted to ignoring advertising to steal some attention back. Most of us (especially geeks) have evolved a personal ‘ad blocker’ in our mind’s eye.

Unfortunately the cost is that it’s become harder to remember importances. So we rely on our mobile technology to inform us when we need to jump to action. As a primitive example, who uses the alarm function on their smart phone? Our phones are our personal assistants. They tell us when our friends are trying to contact us, they act as our saviors when something goes wrong, they entertain us when we’re bored and they tell us important things WHEN we need to know them. Usually, they do this through the notification system. It’s a special sacred system devoted to the most important issues in our lives. This is what’s so wrong about AirPush. They are capitalizing on the cost of our mobile notifications. Technologically speaking, the most important area of our lives. When we hear the distinctive sound, or see that special symbol of our phone’s notification system; we spring into direct action. They are cashing into our need for a system that helps us live our lives, lest we miss opportunities or forget something important.

That’s the basis of my offense. I need my notification system to be personalized and pure because I rely on it to assist me with the day-to-day running of my life.

AirPush says that they’ve changed the API to require opt-in/opt-out due the torrent of outcry and negative feedback that developers have clearly been slammed with but for me, that isn’t really enough. I shouldn’t HAVE to opt-out of something that uses my notification area inappropriately and without permission.  And conversely, if the system is opt-in, then its all but useless to developers (because let’s be honest who would WANT such a thing?)

Frankly, AirPush is a violation of the way I use my mobile devices and I would never abide any application which employed such a system. It’s gotta be the fastest way to get users to uninstall your app.