Alex Pooley's Blog

Hello there, my name is Alex Pooley and I'm a freelance web developer residing in Perth, Western Australia. My passion is in the development of web sites that solve everyday problems. Here's a gallery of some of my notable work. If you need a web site designer or developer, contact me with further details. Lastly, you can read more about me.

typo themes

April 21st, 2006

Sigh. I’ve stuffed around trying to get this blog looking right in all browers but IE is absolutely useless. It appears that IE can’t handle the long lines of code I’m posting these days. For some reason it doesn’t handle the overflowing ‘pre’ tags correctly.

For those who want to use a typo 1.0 theme with their typo edge. You can simply modify theme/the_theme/layouts/default.rhtml and replace the line below:


<%= render_component(:controller => ’sidebars/sidebar’, :action => ‘display_plugins’) %>

with this line…


<%= render_sidebars %>

If you don’t do this you will get an application error.

Anyway, for now I’m just going to stick with typo’s default theme. If you’re using IE you will notice the sidebar has been pushed to the bottom of the page.

typo edge, dreamhost, feedburner

April 20th, 2006

I’ve upgraded this blog from typo stable to typo edge so the source is coming straight out of subversion. It wasn’t as straight forward as I was hoping. Here’s how you can upgrade your stable typo installation to stay on the edge, using dreamhost hosting, and feedburner syndication:

* Backup your old typo blog, including the database.
* No really, backup your blog and db, you may need it later!
* Modify your current blog to point to the ‘azure’ theme otherwise you’ll get an error when starting your new blog.
* Layout your directory structure so that you have something like this for good practice:

/yourdomain.com
/your_backed_up_blog
/current -> /your_backed_up_blog

* Change your hosting settings in Dreamhost so that the doc root is /yourdomain.com/current/public. Your blog should still work once the Dreamhost server updates it’s settings.
* From /yourdomain.com run svn checkout svn://typosphere.org/typo/trunk typo
* Modify the database.yml file to your settings.
* Replace your dispatch.fcgi with:

#!/usr/bin/env ruby
require File.dirname(__FILE__) + “/../config/environment”
require ‘fcgi_handler’

#RailsFCGIHandler.process!

class MyRailsFCGIHandler < RailsFCGIHandler
SIGNALS = {
'TERM' => :exit_now,
}

def exit_now_handler(signal)
dispatcher_log :info, “ignoring request to terminate immediately”
end
end

MyRailsFCGIHandler.process! nil, 25

* Jump in to /yourdomain.com/current and type rake migrate to update your database. Remember to backup your old database first!
* If you’re running with feedburner then to enable autodiscovery of your feedburner feed and not typo’s default feed replace the <%= page_header %> line in typo/themes/azure/layouts/default.rhtml to the following:

<%= javascript_include_tag 'cookies' %>
<%= javascript_include_tag 'prototype' %>
<%= javascript_include_tag 'effects' %>
<%= javascript_include_tag 'typo' %>

* Now modify the feedburner line you just added with your own feedburner feed:
* Note that the previous feedburner mod may get written over when you update your svn export.
* Finally redirect the ‘current’ symlink so that it points to /yourdomain.com/typo. Your dir layout should look like this:

/yourdomain.com
/your_backed_up_blog
/typo
/current -> /typo

You should be done now. If things aren’t working then check your logs for hints. If I’ve left anything out please add comments and I’ll update this post as required.

msgpad development, has_and_belongs_to_many

April 18th, 2006

I’m not sure why, but I hate having to leave code at a point where I know it’s inefficient. There is some code in msgpad right now that is working fine, but at the expense of scalability. I’ve taken the approach of developing the code base so that it is simple. I guess I’ll add complexity later when I need to improve performance.

I’ve performed a major restructure in the code base because things just weren’t playing nicely together. The “perps” were the User, Pad, and the relationship between the two.

A User is obviously someone who uses msgpad.

A Pad is a place where User’s can converse.

The relationship was previously defined by a join table with decorations such as the state of the relationship between the pad and the user. In ruby on rails you define a join table using a has_and_belongs_to_many defintion.

So the User model had

has_and_belongs_to_many :pads

and the Pad model had

has_and_belongs_to_many :users

so if you had a pad object you could do things like

the_pad = Pad.find(1)
for user in the_pad.users
print user.login
end

Cool yeh?

The naming convention for a join table in ruby on rails is to concatenate the two joining table names by a ‘_’ with the table names in alphabetical order. So in this case the join table was ‘pads_users’.

There’s a bit of an issue with this naming convention. pads_users is kind of robotic. Normal people would call the relationship a membership… I think. Fortunately in ruby on rails you can call your model something, and the underlaying table something else via the set_table_name definition in the model. So I renamed my model from PadsUsers to Memberships. As a result I found testing stopped working properly and there were a couple of headaches I don’t recall.

Since then I have redefined the join table as an entity in its own right and called it Memberships. “David” actually says that decorated join tables as models are generally an overlooked solution in his book ‘Agile Web Development With Rails’ on page 241. By making the relationship in this way, we are able to perform operations on the relationship itself.

Each row in Memberships has an id, as well as the foreign keys of the pad and user that it links. So now

Pad model:

has_many :memberships
#This definition is not strictly necessary.
has_many :members, :through=>:memberships, :source=>:user

User model:

has_many :memberships
#This definition is not strictly necessary.
has_many :pads, :through=>:memberships

The equivilent of pad.users before is now pad.members. Alternatively I could solely go through memberships so you would have pad.memberships.each {|user| p user.login}. I also now have the ability to reference the membership explicitly and perform operations on the membership such as changing a membership status. Previously you would have had to do something like the following…


pad.users.find(@alex.id).state = ‘hungry’

or this to add a user to a pad…


pad.push_with_attributes(:user, {:state=>’invited’} )

and here’s an example of an oddity with the habtm relationship (from what I recall from experience):


membership = pad.users.find(@alex.id)
#This won’t work because membership is a User object.
membership.state = ‘hungry’
#This will work… but it’s ugly!
membership = pad.users.find(@alex.id).state = ‘hungry’

anyway, now I simply go…


m = Membership.find_membership(@alex, @the_pad)
m.hungry!
print m.user.name+” is now “+m.state

This arrangement is working well so far and in the future I’ll likely stay away from has_and_belongs_to_many. There are some technical peculiarities that come with the has_and_belongs_to_many relationship that at least for me, make it something to avoid if possible. I’m not entirely sure if having the two has_many’s with one on the join and one on the joined table is going to stuff up query caching. I guess I’ll find out later :)

Let me just disclaim this article by claiming that I am not a guru and am not immune to ignorance.