January 17th, 2008 — IPhone

Version 1.1.3 of the IPhone software (latest version) is currently not jailbreakable which means you cannot install any third party apps.
I have just upgraded my Iphone, it was a difficult decision as was a weigh up between keeping my 30 something apps on the phone or losing it all to the new features such as faux GPS (see feature set here).
I decided to upgrade. There is no problem upgrading a jailbreaked phone, the only downer is that you lose all of the third party apps. You don’t lose your contacts, email or sms. Do not fear! Upgrade now it’s worth it!
On a side note, mid-febuary will see the release of the iphone sdk so loads good stuff to come!
November 30th, 2007 — Ruby On Rails
After performing a Jailbreak (as outlined in my previous post Jailbreak the Iphone, you may find that you have issues connecting to edge.
Here is the solution:
I have only tested this on the O2 UK network.
First make sure the IPhone and your computer are connected to the same wireless network. Now find the ip of your iphone by looking in setting, and then clicking the little arrow beside the wireless network you are connected to.
You need to ssh in to your IPhone, so open up the terminal in mac, or download Putty (a free windows ssh client), and connect to your iphone like this: ssh root@ip_address_of_my_iphone
The password is either alpine or dottie, or whatever you may have set it to if you set it yourself.
now issue the following 3 commands:
rm /var/root/Library/Preferences/com.apple.carrier.plist
ln -s /System/Library/Frameworks/CoreTelephony.framework/Support/O2_UK.plist /var/root/Library/Preferences/com.apple.carrier.plist
rm -f /var/root/Library/Preferences/SystemConfiguration/preferences.plist
Reboot your phone by holding down the turn off button and the home button together and then sliding to power off.
And you should now be back on edge!
November 30th, 2007 — Ruby On Rails
I am a UK IPhone user and recently got the IPhone on the O2 package. But there are so many funky packages I wanted to use, I simply had to jailbreak it!
Here’s how I did it from Version 1.1.2, using my activated IPhone and my Mac running OS X Leopard.
Pre-requisites: You will need to preliminarily down-grade your phone to version 1.1.1, this is available here:
http://appldnld.apple.com.edgesuite.net/content…_3A109a_Restore.ipsw
And also download jailbreak 1.1.2 from here: http://conceitedsoftware.com/iphone/site/112jb.html
2. Reboot your iPhone holding the top (power) and home buttons BUT release the top button 10 seconds into it (right after the screen goes dark) and continue to hold the home button until iTunes detects the phone in recovery mode. The iPhone screen will appear to be off, but start iTunes if not started yet .
3. Restore your iPhone by pressing and holding the ‘Shift’ key on windows or ‘option’ or ‘option and Alt’ key on Mac, then click ‘restore’ to select the 1.1.1 firmware file you downloaded earlier. The restore should go through and errors at the end with error 1015. However you will notice that the iphone is in DFU mode with the connect to itunes screen from 1.1.1.
4. In order to kick the phone out of that mode, start TouchFree by double-clicking “windows.bat”
on Windows or “jailbreak.jar” in OS X, then click the “Boot from Recovery” button. Note: You must quit Itunes for this to work.
(the rest is taken from the README in the Jailbreak download)
—————————————————————————————————-
Step 2a: Jailbreak 1.1.1 on Unactivated iPhone
*** NOTE: If your phone has been activated through iTunes, you can proceed to step 2b. ***
1. enter *#307# press call, now use the back button on the top of your screen to remove *#307#, now enter 0 , press call, press answer, press hold, press decline. And you get to the contact list. And thereafter every time you push the homebutton you just slide the “emergency call” slide, then enter 0 , press call, press hold, press decline.
2. Push contacts, end call and you get called again, this time hit decline and you access one of menus with favorites, you can edit contacts, do a test ride on keyboard, take photos etc.
3. Now edit a new contact and type in “prefs://11″ as web-address and “http://jailbreakme.com” as an additional URL.
4. When you tap “prefs://11″ you can now select your favorite WiFi gateway.
5. Now press the home button and move the slider to the dial-pad.
6. Now you can go back to the contact list by Dialing 0, push call, then answer, then contacts, then hit the “http://jailbreakme.com” web address you typed in.
7. Scroll down to the bottom, click “Install AppSnapp”. Safari will exit and you’ll return to your springboard. Wait for the phone to reboot. You are now jailbroken. and are able to use Installer.app.
—————————————————————————————————-
Step 2b: Jailbreaking on iPod Touch or iTunes Activated iPhone
1. Launch Safari
2. Visit http://jailbreakme.com, Scroll down to the bottom, click “Install AppSnapp”. Safari will
exit and you’ll return to your springboard. Slide to unlock, you are now jailbroken. and are able to use Installer.app.
—————————————————————————————————-
Step 3: Prepare your 1.1.1 device for the Update
1. Launch Installer.app
2. Scroll down to Tweaks (1.1.1)
3. Select OktoPrep
4. Click Install
—————————————————————————————————-
Step 3b: Prevent SpringBoard crash on previous hacked iPod touches
If you have installed MobileMail on your iPod touch, there is a chance an update to 1.1.2 will render your device inoperable until a restore. This issue can be prevented by switching Auto-Check off.
- Go to General->Mail->Auto-Check. Set it to Manual.
If you forget to do this step and update, proceed with the jailbreak in step 5 (even though SpringBoard is unusable) and we will fix it for you.
—————————————————————————————————-
Step 4: Update to 1.1.2
1. Connect your device to your computer
2. Launch iTunes
3. Choose your device. Click Update
- If update still shows 1.1.1 as being the newest version, you may download the 1.1.2 from an Apple download server and shift-click (PC) or option-click (Mac) on “Check for update” and select the update you downloaded.
- DO NOT CLICK OR SHIFT-CLICK RESTORE: That will wipe the changes OktoPrep made.
5. Wait forever for your device to update
—————————————————————————————————-
Step 5: Jailbreak your iPod Touch or iPhone
WARNING: If your iPhone is unactivated, it will be factory “hactivated” for you and YouTube enabled.
If this is not desired behavior, activate your iPhone with iTunes before proceeding.
1. Close iTunes
2. Connect your device to your computer
3. On Windows, double click on windows.bat, on Mac, double click on jailbreak.jar
4. Follow the on screen instructions.
****FINALLY!!******
Now you need to run Jailbreak again. This time you need to select Jailbreak my phone,
You can also click on install ssh if you want that too.
Your phone should reboot a couple of times, and there you have it! Jailbreaked iphone
Now if you are on O2 in the UK, you will find that edge no longer works. This is quickly solved by checking out my next blog post here
November 27th, 2007 — IPhone
I got an IPhone the other day, and it is great!
I have about 250 contacts on my nokia n95 and wanted to import the lot over. Unfortunately the IPhone does not support VCard sending via Bluetooth, the bluetooth functionalities of the IPhone are pretty limited. This is a shame as if it had this would have been so easy to do.
First enable bluetooth on your N95, in tools, bluetooth.
Anyways, first off you need to get your contacts off your n95. You do this using the ISync software that comes pre-installed on the Mac, but you need the Nokia n95 plugin for ISync available here: http://europe.nokia.com/A4299040.
Then its as simple as syncronising your contacts using ISync from your phone to your apple address book.
Once all of your contacts have been exported, plug in your IPhone and set up the synchronizations on ITunes so that it merges data from address book to phone. Your contacts should now be transferred!
November 22nd, 2007 — Ruby On Rails
I want multiple apps running on one machine. Each app has a nginx server with 4 mongrels sitting behind it. Here is my setup:
1. Install Ubuntu 7.10, and sudo apt-get install subversion and sudo apt-get install mysql-server
2. Follow first page of Rubyworks install here: http://rubyworks.rubyforge.org/installation/ubuntu.html
3. Install Nginx by typing: sudo apt-get install nginx
4. Here is my nginx config for my first app, which I have saved in /etc/rails/my_first_app/nginx.conf
# user and group to run as
user jason jason;
# number of nginx workers
worker_processes 1;
# pid of nginx master process
pid /var/run/nginx_my_first_app.pid;
# Number of worker connections. 1024 is a good default
events {
worker_connections 1024;
use epoll; # linux only!
}
# start the http module where we config http access.
http {
# pull in mime-types. You can break out your config
# into as many include’s as you want to make it cleaner
include /etc/nginx/mime.types;
# set a default type for the rare situation that
# nothing matches from the mimie-type include
default_type application/octet-stream;
# configure log format
log_format main ‘$remote_addr - $remote_user [$time_local] ‘
‘”$request” $status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;
# main access log
access_log /var/www/apps/my_first_app/shared/log/nginx/access.log main;
# main error log - Do not comment out. If you do not want the log file set this to /dev/null
error_log /var/www/apps/my_first_app/shared/log/nginx/error.log notice;
# no sendfile on OSX
sendfile on;
# These are good default values.
tcp_nopush on;
tcp_nodelay on;
# output compression saves bandwidth
gzip on;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# this is where you define your mongrel clusters.
# you need one of these blocks for each cluster
# and each one needs its own name to refer to it later.
upstream mongrel {
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
server 127.0.0.1:3004;
}
# uncomment if you want to always redirect to www.
#server {
# listen 80;
# server_name exmaple.com;
# rewrite ^.*$ http://www.example.com;
#}
# the server directive is nginx’s virtual host directive.
server {
# port to listen on. Can also be set to an IP:PORT
listen 3000;
# Set the max size for file uploads to 50Mb
client_max_body_size 50M;
# doc root
root /var/www/apps/my_first_app/current/public;
# vhost specific access log
access_log /var/www/apps/my_first_app/shared/log/nginx/vhost.access.log main;
# this allows people to use images and css in their maintenance.html file
if ($request_filename ~* \.(css|jpg|gif|png)$) {
break;
}
# this rewrites all the requests to the maintenance.html
# page if it exists in the doc root. This is for capistrano’s
# disable web task
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html last;
break;
}
location / {
index home.html index.html index.htm;
# needed to forward user’s IP address to rails
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
proxy_max_temp_file_size 0;
#location ~ ^/(images|javascripts|stylesheets)/ {
# expires 10y;
#}
if (-f $request_filename) {
break;
}
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
# this is the meat of the rails page caching config
# it adds .html to the end of the url and then checks
# the filesystem for that file. If it exists, then we
# rewite the url to have explicit .html on the end
# and then send it on its way to the next config rule.
# if there is no file on the fs then it sets all the
# necessary headers and proxies to our upstream mongrels
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
proxy_pass http://mongrel;
break;
}
}
error_page 400 /400;
error_page 500 502 503 504 /500.html;
location = /500.html {
root /var/www/apps/my_first_app/current/public;
}
location = /400 {
return 400;
}
}
}
5. In /etc/rails/my_first_app I also place 4 mongrel configs called mongrel_3001.conf … mongrel_3004.conf
With the following inside each one:
—
:cwd: /var/www/apps/my_first_app/current/
:log_file: /var/www/apps/my_first_app/shared/log/mongrels/mongrel_3001.log
:daemon: false
:debug: false
:environment: production
:port: 3001
:num_processors: 5
obviously thats the 3001 config, you need to modify 3001 to 3002 etc depending on which mongrel config it is (3001, 3002, 3003 or 3004)
6. Now to edit the services run by monit
First cd /var/service sudo rm -Rf mongrel* to remove current mongrel configs
Then sudo rm -Rf /var/service/haproxy to remove ha proxy
This leaves you with only monit
7. Do: sudo mkdir my_first_ap_mongrel_3001, sudo mkdir my_first_ap_mongrel_3002, sudo mkdir my_first_ap_mongrel_3003, sudo mkdir my_first_ap_mongrel_3004 and sudo mkdir my_first_ap_nginx_3000
8. Now create a run file (executable sudo chmod +x run) inside each of these directories with the following info:
For the mongrels:
#!/usr/bin/env ruby
# Doing it this way, instead of simple ’sudo -u rails exec …’ gets around a sudo bug in RHEL/CentOS 4,
# described in http://bugs.centos.org/view.php?id=1650
require ‘etc’
Process::GID.change_privilege(Etc.getgrnam(’rails’).gid)
Process::UID.change_privilege(Etc.getpwnam(’rails’).uid)
exec ‘/usr/bin/mongrel_rails start -c /usr/rails -C /etc/rails/my_first_app/mongrel_3001.config’
changing the number for which ever mongrel
and for nginx:
#!/bin/sh
exec /usr/sbin/nginx -c /etc/rails/my_first_app/nginx.conf
7. Nearly there! Now edit sudo vi /etc/rails/monit.conf
Delete it all and change it to this:
# Configuration for Monit, a monitoring tool
# whose role in RubyWorks stack is to ensure that other components
# are up and running at all times.
#
# Original documentation for Monit is here:
# http://www.tildeslash.com/monit/doc/manual.php
set daemon 15 # Perform a check every 15 seconds
set logfile /var/log/monit.log
# set mailserver mail.bar.com
# set alert admin@bar.com
# mail-format {
# from: rubyworks@rubyforge.org
# subject: $SERVICE $EVENT at $DATE
# message: Monit $ACTION $SERVICE at $DATE on $HOST,
#
# Yours sincerely,
# RubyWorks.
# }
# This section configures Monit’s web frontend on port http://localhost:80.
set httpd port 80 and
# only accept connection from localhost. Change to 0.0.0.0 to accept
# remote connections. Make sure to change the password in the ‘allow’
# statement if you do.
use address 0.0.0.0
# When someone connects to the web frontend, perform basic HTTP i
# authentication and accept username/password admin/MonitPa$$w0rd
allow admin/MonitPa$$w0rd
check process my_first_app_nginx_3000
with pidfile “/var/service/my_first_app_nginx_3000/supervise/pid”
start program = “/usr/bin/sv up my_first_app_nginx_3000″
stop program = “/usr/bin/sv down my_first_app_nginx_3000″
if totalmem is greater than 100.0 MB for 4 cycles then restart
if failed port 3001 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout
check process my_first_app_mongrel_3001
with pidfile “/var/service/my_first_app_mongrel_3001/supervise/pid”
group mongrels_my_first_app
start program = “/usr/bin/sv up my_first_app_mongrel_3001″
stop program = “/usr/bin/sv down my_first_app_mongrel_3001″
if totalmem is greater than 110.0 MB for 4 cycles then restart
if failed port 3002 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout
check process my_first_app_mongrel_3002
with pidfile “/var/service/my_first_app_mongrel_3002/supervise/pid”
group mongrels_my_first_app
start program = “/usr/bin/sv up my_first_app_mongrel_3002″
stop program = “/usr/bin/sv down my_first_app_mongrel_3002″
if totalmem is greater than 110.0 MB for 4 cycles then restart
if failed port 3002 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout
check process my_first_app_mongrel_3003
with pidfile “/var/service/my_first_app_mongrel_3003/supervise/pid”
group mongrels_my_first_app
start program = “/usr/bin/sv up my_first_app_mongrel_3003″
stop program = “/usr/bin/sv down my_first_app_mongrel_3003″
if totalmem is greater than 110.0 MB for 4 cycles then restart
if failed port 3002 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout
check process my_first_app_mongrel_3004
with pidfile “/var/service/my_first_app_mongrel_3004/supervise/pid”
group mongrels_my_first_app
start program = “/usr/bin/sv up my_first_app_mongrel_3004″
stop program = “/usr/bin/sv down my_first_app_mongrel_3004″
if totalmem is greater than 110.0 MB for 4 cycles then restart
if failed port 3002 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout
8. It’s now time to deploy!
Using your deploy file, here is mine as an example (place this in your rails project config/deploy.rb:
# =============================================================================
# ENGINE YARD REQUIRED VARIABLES
# =============================================================================
# You must always specify the application and repository for every recipe. The
# repository must be the URL of the repository you want this recipe to
# correspond to. The deploy_to path must be the path on each machine that will
# form the root of the application path.
set :keep_releases, 3
set :application, ‘my_first_app’
set :user, ‘jason’
set :password, ‘my password for my user’
set :repository, ‘https://my_svn.com/trunk’
set :svn_username, ‘jason’
set :svn_password, ‘hello svn password’
set :deploy_to, “/var/www/apps/#{application}”
set :checkout, “export”
set :monit_group, ‘mongrels_my_first_app’
set :use_sudo, true
set :rails_env, “production”
# =============================================================================
# ROLES
# =============================================================================
# You can define any number of roles, each of which contains any number of
# machines. Roles might include such things as :web, or :app, or :db, defining
# what the purpose of each machine is. You can also specify options that can
# be used to single out a specific subset of boxes in a particular role, like
# :primary => true.
task :production do
role :web, ‘ip_address_of_ubuntu_server’
role :app, ‘ip_address_of_ubuntu_server’
role :db, ‘ip_address_of_ubuntu_server’, :primary => true
end
# =============================================================================
# TASKS
desc “Long deploy will throw up the maintenance.html page and run migrations
then it restarts and enables the site again.”
task :long_deploy do
transaction do
update_code
migrate
end
restart
end
task :revision, :roles => :app do
run %(tail -1 #{deploy_to}/revisions.log)
end
desc <<-DESC
Restart the Mongrel processes on the app server by calling restart_mongrel_cluster.
DESC
task :restart, :roles => :app do
restart_mongrel_cluster
end
desc <<-DESC
Start the Mongrel processes on the app server by calling start_mongrel_cluster.
DESC
task :spinner, :roles => :app do
start_mongrel_cluster
end
desc <<-DESC
Start Mongrel processes on the app server. This uses the :use_sudo variable to determine whether to use sudo or not. By default, :use_sudo is
set to true.
DESC
task :start_mongrel_cluster , :roles => :app do
sudo “monit start all -g #{monit_group}”
end
desc <<-DESC
Restart the Mongrel processes on the app server by starting and stopping the cluster. This uses the :use_sudo
variable to determine whether to use sudo or not. By default, :use_sudo is set to true.
DESC
task :restart_mongrel_cluster , :roles => :app do
sudo “monit restart all -g #{monit_group}”
end
desc <<-DESC
Stop the Mongrel processes on the app server. This uses the :use_sudo
variable to determine whether to use sudo or not. By default, :use_sudo is
set to true.
DESC
task :stop_mongrel_cluster , :roles => :app do
sudo “monit stop all -g #{monit_group}”
end
9. from your local machine within your rails project root type: cap production setup, then cap production cold_deploy
10. Finally type: cap production long_deploy
11. your app should be deployed!
November 21st, 2007 — Ruby On Rails
Yesterday I wrote a post about getting rubyworks running on 7.10. Today I am going to run through the steps of getting it working on 7.04 (Feisty Fawn).
1. Install 7.04 with LAMP server ticked, this will amongst other things, get mysql server running.
N.B. do not call your user rails as rubyworks uses this user.
2. Reboot, and edit the /etc/apt/sources.list file. Remove the following line:
deb cdrom:[Ubuntu-Server 7.04 _Feisty Fawn_ - Release i386 (20070415)]/ feisty main restricted
This will stop apt-get installing packages from the cdrom, and look on the internet instead.
3. Now run sudo apt-get update to get the updated list of packages
4. Install openssh server so you can continue the rest of this guide remotely (from another computer) by typing: sudo apt-get install openssh-server
5. Find out the IP address of your server by typing ifconfig. If your connection is via ethernet, your ip address will probably be in the eth0 settings.
6. Go to your other computer and open up a terminal window (in windows download putty, on mac osx go to utilities, terminal in your finder. Connect to your ubuntu box by typing: ssh username_i_chose_on_ubuntu_install@my_ip_address_of_ubuntu_box
7. You are now ready to install rubyworks. Follow the guide here: http://rubyworks.rubyforge.org/installation/ubuntu.html
NB if you get an error on install of the type:
A package failed to install. Trying to recover:
Setting up rubyworks (1.0.0) …
Checking installation …
ls /etc/rails
haproxy.conf mongrel_3003.config mongrel_3005.config monit.pem
mongrel_3002.config mongrel_3004.config monit.conf
/usr/lib/ruby/1.8/fileutils.rb:1184:in `stat’: No such file or directory - /tmp/sources.rb (Errno::ENOENT)
from /usr/lib/ruby/1.8/fileutils.rb:1184:in `lstat’
from /usr/lib/ruby/1.8/fileutils.rb:1162:in `stat’
from /usr/lib/ruby/1.8/fileutils.rb:1244:in `copy_file’
from /usr/lib/ruby/1.8/fileutils.rb:459:in `copy_file’
from /usr/lib/ruby/1.8/fileutils.rb:383:in `cp’
from /usr/lib/ruby/1.8/fileutils.rb:1379:in `fu_each_src_dest’
from /usr/lib/ruby/1.8/fileutils.rb:1395:in `fu_each_src_dest0′
from /usr/lib/ruby/1.8/fileutils.rb:1377:in `fu_each_src_dest’
from /usr/lib/ruby/1.8/fileutils.rb:382:in `cp’
from /var/lib/dpkg/info/rubyworks.postinst:18
dpkg: error processing rubyworks (–configure):
type: sudo touch /tmp/sources.rb, and then run sudo aptitude install rubyworks again!
Thats your rubyworks stack running.
Next post wil be how to get capistrano deployments working on the stack.
November 20th, 2007 — Ruby On Rails
Rubyworks stack does not run entirely out of the box on Ubuntu Gusty Gibbon (7.10).
Here are a couple of things I did to get it working.
1. Following the readme for 7.04 on rubworks here: http://rubyworks.rubyforge.org/installation/ubuntu.html.
2. You get to
If all goes well, you now have a skeleton Rails application up and running at http://localhost:3001. There is also monitoring console running at http://localhost:2812. Congratulations!
and it probably won’t be running.
Solution: just run: sudo runsvdir-start
3. Then continue with the tutorial, make sure to change the port for the webserver from 3001 to 80. Tutorial is here: http://rubyworks.rubyforge.org/installation/ubuntu.html.
4. You need to configure your iptables to allow traffic into port 80 (and 2812 if you want to access monit from outside of localhost).
To do this you need to type this:
sudo iptables -A INPUT -p tcp --dport http -j ACCEPT
and
sudo iptables -A INPUT -p tcp --dport 2812 -j ACCEPT
Now try and connect to your machine from another!
N.B. opening 2812 for monit like this is a security risk, so follow the instructions on how to set up ssl etc if your server is on the internet
And that’s about it!
January 25th, 2007 — Ruby On Rails
If you want to pass a parameter through a form, you don’t pass it through submit_tag, you pass it in start_form_tag. For example, I want to pass the value of id:
<%= start_form_tag :action => ‘create’, :id => @thisparticularid %>
This is much more secure than using a hidden field, for obvious reasons!
January 24th, 2007 — Ruby On Rails
Using has_and_belongs_to_many is great if you want to manage simple HABTM assoctions, although it provides no access as far as I am aware to other attributes if present in the join table. For a more complex join, you’ve gotta code it by hand.
I came across a bug with HABTM today. Do not add an id field to the join table, if you do, the habtm join table id will be populated to contain the id of your joined model, rather than an auto-incremented number.
This inevitably leads to problems! Check out the habtm reference here for more info.
January 10th, 2007 — General
After spending the summer developing a Ruby on Rails web 2.0 community app, I needed to pay the bills so I started work in December for Armstrong International as a Web developer in Ruby on Rails
I have found a sweet flat in Bayswater, London, and will be moving in as soon as possible!