Courtesy of Twitter

Archive for September, 2008

The Super-Consumer

Tuesday, September 30th, 2008

So I have this friend who’s the same age as me. He doesn’t work. He doesn’t appear to be actively looking for work. He got “fired” from his last job because he wasn’t fast enough, but apparently the boss was an asshole. There was an excuse for the job before it too, but I can’t remember what that was. He’s constantly getting new things. I’d like to refer to him as a “super-consumer”, someone who has too much. He loves NERF and Transformers (keeping in mind he’s the same age as me). He’s never outwardly happy with the things he has, and is constantly in a “covet thy neighbour” state of mind (and he’s Christian!), always wanting the next level up as soon as it’s been released. Take for instance the graphics card I won at AsLAN in a silent auction. He asked me if I could put my brand new graphics card into his media center. His argument was for when he has movie nights, then I will appreciate the gift I gave unto him. Admittedly, it’s a card I have no use for, at the moment, but it’s always handy to have a spare in case things go wrong. So, rather than him actually putting the energy used into his craving for all that is new & shiny into finding work so that he can buy all that is new & shiny, he just craves. I think this path is going to destroy him, and there’s nothing I can do or say that will open his eyes to what he is bringing on himself.

A List of Police-related Shows on Australian Free-to-air TV

Monday, September 29th, 2008

The Bill
Taggart
CSI: Miami
Crime Investigation Australia
CSI: NY
Dexter
Bones
City Homicide
The Force - Behind the line
Border Security - Australia’s Front Line
NCIS
Criminal Minds
Life
Law & Order: Criminal Intent
Law & Order: SVU
Motorway Patrol
Police Ten 7
Miami Vice
The Strip
Inspector Rex

Single Table Inheritance

Sunday, September 28th, 2008

This tutorial was written using Ruby 1.8.6, Rails 2.1.

A lot of the time I see people asking how they can do something like access levels for their Rails applications and this usually boils down to some STI (single table inheritance) love. You’ll need to have restful_authentication installed.

What is Single Table Inhertiance?

Single Table Inheritance is where you have multiple models that inherit from a single table, hence the name. It’s great for situations like this where we want multiple user access levels, but we don’t want to create multiple tables for the different kinds of users of our application.

Okay.. so how do I use it?

Firstly you start off with one model that inherits from ActiveRecord::Base, and I would advise running script/generate authenticated person session to get this:

app/models/person.rb

class Person < ActiveRecord::Base
 
end

And then you subclass some other classes from Person
app/models/student.rb

class Student < Person
 
end

app/models/teacher.rb

class Teacher < Person
 
end

app/models/admin.rb

class Admin < Person
 
end

The great thing about splitting these into individual files is because they’re more easily managed and closely follows the convention of one model per file.

Now you have a person, student and teacher model and you should have a brand new migration for your people table in db/migrate so go on and open that up and you’ll see something like this:

class CreatePeople < ActiveRecord::Migration
  def self.up
    create_table "people", :force => true do |t|
      t.column :login,                     :string, :limit => 40
      t.column :name,                      :string, :limit => 100, :default => '', :null => true
      t.column :email,                     :string, :limit => 100
      t.column :crypted_password,          :string, :limit => 40
      t.column :salt,                      :string, :limit => 40
      t.column :created_at,                :datetime
      t.column :updated_at,                :datetime
      t.column :remember_token,            :string, :limit => 40
      t.column :remember_token_expires_at, :datetime
 
    end
    add_index :people, :login, :unique => true
  end
 
  def self.down
    drop_table "people"
  end
end

To enable STI for this table, just add:

t.column :type, :string

into the create_table block, just after t.column :remember_token_expires_at, :datetime. This type column will be set to whatever class the record is, so if we create a new Student object, this type column will be set to “Student”.

Controllers

To create new objects for these subclasses I would recommend building a people controller and using the form partial from that to base your form off from the other controllers, such as StudentsController and TeachersController. These controllers should NOT subclass from PeopleController, they should be their own independent controllers because Teachers, People and Students are all individual resource types.

Associated Models

If you have associated models (e.g. Person has_many :enrolments), any subclass of Person will inherit this relationship. For the relationship, this will be referenced via person_id still in the enrolments table.

How To Ask For Help

Thursday, September 25th, 2008
  1. Have you tried stopping your server and starting it? This fixes many problems and may fix yours!
  2. If you’re getting a NoMethodError which ends in “The error occured when evaluating nil.method” this means you’re trying to call a method on a nil object! Check the object that you’re calling that method on and make sure that it actually is set!
  3. Google the error message. If you’re getting “undefined method `blah`”, try googling just “undefined method”. Never ask a question without googling first.
  4. State your problem clearly. Never, ever say “I have a problem plzzzz help me !!!1!” or ” is not working” or something to that effect. Say, for example, that you’re getting an undefined method. Type “pastie: hi” into the channel and the pastie bot will send you a link via private message where you can show us your code, stack trace and error. Giving all three will provide us 99% of the time with the information we need to help you solve your problem.
  5. Don’t use dummy examples. An example would be asking a question like “How does A relate to B?” when asking “How does a blog relate to comment?”.
  6. Don’t ask “can you do <thing> with Rails?”, because the most often answer is “Yes”. Ask rather “How can you do <thing> with Rails?”
  7. Don’t ask to ask, just ask.
  8. Paste anything over 3 lines of code using the pastie service (type “pastie: hello”) into the channel and the pastie bot will send you a link via private message where you can put your code.
  9. Don’t ask “Has anybody used <thing>?” rather state your problem that you’re having with <thing> and somebody may be able to help you. See #2.
  10. Don’t prefix your question with a statement or another question. For example just write your problem rather than prefixing it with something like “Can anyone help me with this? <problem>” or “I am a noob help me with <problem>” or “I have a problem… <problem>” it’s a waste of your time typing it out and a waste of our time reading it.
  11. Computers never lie.
  12. Don’t ask subjective questions. “Subjective” means a question that’s answer is entirely opinion based, such as questions like “What is the best text editor?” or “What is the best testing framework?”

And Now For Something Completely Useless

Tuesday, September 23rd, 2008
class Model < ActiveRecord::Base
  has_many (Dir.entries("#{RAILS_ROOT}/app/models")-['.','..',"#{self.to_s.downcase}.rb"]).delete_if{|a|
File.directory?("#{RAILS_ROOT/app/models/#{a}")}.rand.gsub(".rb","").pluralize.to_sym
end

Parking

Wednesday, September 17th, 2008

An idea that’s been playing around in my head today:

Twonklist

Tuesday, September 16th, 2008

The site twonklist.com was an idea conceived of at my last job (NetFox) and I coded it up in a night or two with Brenton Fletcher adding the styling in later on.

This afternoon it was defaced. I have since removed all the awesome pictures a certain person put on the site, and it’s a person who apparently has a grudge against me. Now, I know who this person is. I even know their IP is 122.109.249.211. I know their ISP is Optus. I’ve even sent an email (with screenshots!) in the vain hope that they’ll do something about it, but they most likely will not. Now if you have a grudge against me, the way to go about things is to not deface any of my sites. You come to me, face to face, as a man and talk to me. I’m available most days. Say what you like, just don’t deface my sites.

Congratulations to this person, as now all the requests from any IP beginning with 122.109 will go to a very useful/useless google search entry. Yes, that basically means the entire Optus network.

The Accident: Followup #1

Monday, September 15th, 2008

This is a followup to my InLAN blog post, best to read that first to get the whole story.

So today I get a phone call from Allianz about my compulsory 3rd party insurance and they told me the guy is filing a personal injury claim and apparently has “legal representation”. They asked me all kinds of questions like “Were you using a mobile phone?”, “Did you get alcohol testing?”, “Were you and your passenger wearing a seatbelt?” and so on.

What really amazes me is that someone who, despite the thousands of years of evolution the human race has undergone, still thinks it possible to file a personal injury claim for an accident he caused. Had he not bolted out of the bushes onto the road, whilst it was raining AND in the middle of the night, this would have never happened. You (and the insurance company) can only take my word that I’m not a homocidal maniac who enjoys late night rampages that involve running over pedestrians and causing hundreds of dollars worth of damage to my dearly beloved car, not to mention my state of mind.

If I have to pay this guy a cent, that will be the last of my faith in humanity gone for quite a while.

Ham & Rocket Rolls

Wednesday, September 10th, 2008

Usually I post technically minded stuff, but today I decided to share my “recipe”. Mum and Darrel have gone away for a month so I’ve been left to fend for myself with my cooking skills near to non-existant. I can microwave, I can toast and I can simmer.

For the past few days I’ve been eating these hamburger rolls from woolworths stuff with various ingredients and I’ve found that ham (any kind) and cream cheese go nicely together. I tweeted yesterday about having the rolls and got the opposite reaction to what I expected, nikc recommended I try putting rocket on it. Also with me being a long-time fan of cream cheese and sweet chilli sauce (the only two liquids I find that complement each other so perfectly), I put that on the roll too.

“What was the end result?”, I hear you speak through the saliva drooling from your mouth. It was this:

Ingredients

  • Knife to cut rolls
  • Sandwich Toaster (optional)
  • 1 Hamburger Roll
  • Cream Cheese
  • Sweet Chilli Sauce
  • Rocket leaves
  • Honey Baked Ham

Preparation:

  1. Cut rolls directly down the middle and lightly toast them for about a minute on the sandwich toaster (optional)
  2. Spread cream cheese lightly on both sides of the rolls
  3. Put ham on top of the cream cheese
  4. Put a drop of sweet chilli sauce on the ham and spread
  5. Tear off some rocket leaves and spread over ham
  6. Put roll back together

Thanks to the viscosity of the cream cheese and sweet chilli sauce combination, your roll should stay nicely packed together.

Photos are here and here!

Ubuntu, Rails, Apache, Passenger, Capistrano & You

Wednesday, September 3rd, 2008

Now What?

So you’ve got a freshly installed copy of Ubuntu Server, you’ve logged into the server with your intent being to create a Rails server… only you don’t know how or you’re not entirely sure. Good thing this guide’s here to guide you through that.

Right now you should have a prompt like this: you@server:~$ _. If you don’t, I can recommend one of three things:

  1. Turn on your screen.
  2. Log into the server (if it’s remote)
  3. Install the operating system first.

Other than that, you’re on your own.

I would recommend running sudo apt-get dist-upgrade right now. This should only take a few seconds as it downloads and installs all the packages.

The next thing we want to install is build-essential, which can be done by typing: sudo apt-get install build-essential and this will install all the essential packages you need in order to compile stuff on your machine.

We’ll now want to add a user that we can deploy to. We’ll call this user deploy and we’ll add it using useradd deploy -m with the -m option creating the /home/deploy directory for us.

MySQL users

You’ll need to install MySQL by issuing sudo apt-get install mysql-client-5.0 mysql-server-5.0 libmysqlclient15-dev

PostgreSQL users

You’ll need to install PostgreSQL (unless you selected that option when installing Ubuntu Server) by issuing sudo apt-get install postgresql

Ruby, Ruby, Ruby, Ruby!

Now you’ll need to install ruby and all the associated packages, using the command that resembles this: sudo apt-get install ruby-full ruby1.8-dev and will install the following packages:

irb1.8: Interactive Ruby Console, letting you type Ruby code and see the output immediately. Useful because it stops you from creating files like test.rb, and then running them once using ruby test.rb and then forgetting about them.
libopenssl-ruby1.8: Enables Ruby to use SSL.
libreadline-ruby1.8: Enables Ruby to use the readline library, for line editing and whatnot.
libruby-1.8 & ruby1.8 & ruby 1.8-dev: Collection of libraries to run Ruby and development headers.
rdoc1.8 & rdoc: Ruby Document Generator, necessary for generating document down the road.
ri1.8 & ri : Plain-text based version of the Ruby docs. Example ri Integer will show useful information about the Integer class.

Ruby is now installed as ruby1.8. Now, if you’re like me and don’t like typing any more than you have to, you can symbolically link this ruby1.8 file to just /usr/bin/ruby. To do this, just type sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby and it’s all done. This way, you can type ruby AND ruby1.8 and it’ll do the same thing.

After that’s all done, head over to the the rubygems download page and get Rubygems 1.3.1, unpack it and install it yourself. Alternatively, you could use this command and it’ll download it, unpack and install it for you and do some clean up after:

wget http://rubyforge.org/frs/download.php/38646/rubygems-1.3.1.tgz &&
gunzip rubygems-1.3.1.tgz &&
tar xf rubygems-1.3.1.tar &&
cd rubygems-1.3.1 &&
sudo ruby setup.rb &&
cd .. &&
rm -r rubygems-1.3.1*

Rubygems installs an executable called gem1.8, which again is more typing than what we need. We’ll just symbolically link this one too: sudo ln -s /usr/bin/gem1.8 /usr/bin/gem

Now we can install Rails, Passenger and Mongrel by typing sudo gem install rails passenger mongrel. This will install Rails, Passenger and Mongrel, along with all the required dependencies.

Apache & Passenger

The next step is to install apache: sudo apt-get install apache2-mpm-prefork apache2-prefork-dev which will install a whole slew of packages including an apache2 server and the development headers for it, too many in fact that I shall not list them here! Just trust me on this one.

After this is done, run sudo passenger-install-apache2-module and follow the instructions there. After it’s done pay attention to the last three lines it tells you to put into your apache configuration file:

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.3/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.3
PassengerRuby /usr/bin/ruby1.8

For that last line, you can use either /usr/bin/ruby1.8 or /usr/bin/ruby, since we symbolically linked them all that time ago. We’re going to put these lines into /etc/apache2/sites-enabled/000-default at the top of the file and change a few things in the file and our end result should look like this:

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.3/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.3
PassengerRuby /usr/bin/ruby1.8

NameVirtualHost *

  ServerAdmin you@somewhere.com
  DocumentRoot /home/deploy/app/current/public
  ErrorLog /var/log/apache2/error.log
  LogLevel warn
  CustomLog /var/log/apache2/access.log combined
  ServerSignature On

After editing this file you’ll need to restart Apache by typing: sudo /etc/init.d/apache2 restart. Also, you may want to remove the index.html file currently residing in /var/www by tpying sudo rm /var/www/index.html

Capistrano

Now you want to deploy your uber-mega-ultra-hyper application to the server! To do this we can use Capistrano. If you haven’t already, on your development machine install Capistrano by typing sudo gem install capistrano. When Capistrano is installed go into your uber-mega-ultra-hyper application’s root directory and type capify .. This will capify (say it out loud in an announcer-style voice, oh yeah) your application by creating a Capfile in the root path and a deploy.rb file in the config folder. What we’re really interested in here is the config/deploy.rb file which now looks kind of sparse:

set :application, "set your application name here"
set :repository,  "set your repository location here"
 
# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
# set :deploy_to, "/var/www/#{application}"
 
# If you aren't using Subversion to manage your source code, specify
# your SCM below:
# set :scm, :subversion
 
role :app, "your app-server here"
role :web, "your web-server here"
role :db,  "your db-server here", :primary =&gt; true

But we’ll give it some lovin’:

set :application, "uber-mega-ultra-hyper"
set :repository, "git://github.com/you/uber-mega-ultra-hyper"
 
set :deploy_to, "/home/deploy/app"
set :scm, :git
 
role :app, "uber-mega-ultra-hyper.com"
role :web, "uber-mega-ultra-hyper.com"
role :db, "uber-mega-ultra-hyper.com", :primary =&gt; true
 
namespace :passenger do
  task :restart do
    run "touch #{current_path}/tmp/restart.txt"
  end
end
 
after :deploy, "passenger:restart"
Git Users: You’ll need to run apt-get install git-core if you want to use git with Capistrano. Also, if you’re wanting to deploy a branch it’s best to specify a set :branch, “your-branch” in the config/deploy.rb file, otherwise Capistrano will checkout HEAD.

Subversion Users: You’ll need to run apt-get install subversion if you want to use svn with Capistrano.

We’ve just changed all the default values to stuff that’s relevant to us, and removed all the comments from the file. The default scm for capistrano is SVN, but in this example we use git (shown as the repository URL and scm), so we have to set the scm to be git. Right at the end of the file we put in a small snippet of code that will restart passenger after we deploy. Simple really!

If you’re like me and you’ve ignored your config/database.yml file from your repository, you may want to create one. The great thing about Capistrano is that you can put files like this in a shared directory. I’ve put a database.yml file for my application in /home/deploy/app/shared/config. Right now, you wouldn’t have a /home/deploy/app/shared directory unless you created it so go right ahead now and create it using (while logged in as deploy): mkdir -p ~/app/shared/config ~/app/shared/log ~/app/shared/system. This command will also create the config, log and shared directories. Two of these directories, log and shared are symbollically linked from current/log to shared/log and current/public/system to shared/system respectively. Go ahead now and create your shared/config/database.yml file.

In your Rails application’s root directory, type cap deploy to put your application on the remote server. You may be prompted for a password. When that’s done, go have a look at your application and make sure everything is functioning correctly.

That’s all from the guide, I hoped you enjoyed it and learned something.