Monday, December 17, 2007

Auto reverting Migrations

I often end up writing some code in self.up that craps out and it is painful to reverse any database changes that may have been committed. I often resort to revert to an earlier version, but that is an extra step I would rather not have to do.

I make sure all the extra code is located after any database changes I want to make and then wrap the whole shebang in a begin-rescue block:

class FixCategoriesOrder < ActiveRecord::Migration
def self.up
begin
add_column :categories, :sort_order, :integer
# ... other database changes

# Code
[["Immunology", 1],
["Biochemistry", 2],
["Biotechnology", 3],
["Cell Biology", 4],
["Genomics", 5],
["Plant Biology", 6],
["Developmental Biology", 7],
["Ecology", 8],
["Other", 100]].each do |ar|
puts "Processing #{ar[0]} - #{ar[1]}"
Category.find_by_name(ar[0]).update_attribute(:sort_order, ar[1])
end
rescue
self.down
raise $!
end

end

def self.down
remove_column :categories, :sort_order
end
end



Njoy

link_to helper, popup option and IE window.open

Ah, the amount of time spent on this could have really been well spent elsewhere!

If you trying to use link_to as below:

link_to "View Image", { :action => "view" }, :popup => ['new_window_name', 'height=300,width=600']
# => View Image


Be very careful when you specify 'new_window_name'.

It shouldn't have any embedded spaces in the string.

Else IE will barf and throw a runtime exception! Firefox works fine though.

Sunday, December 16, 2007

has_and_belongs_to_many (HABTM) and MySQL Duplicate entry error

A quick post:
If you use migrations to create a join table for a HABTM relationship, you should tell rails not to automatically add an id column in the migration (Agile book - 271).
Otherwise you will get a
Mysql::Error: Duplicate entry '#' for key #
error.


create_table :authors_books, :id => false do |t|
t.column :author_id, :integer, :null => false
t.column :book_id, :integer, :null => false
end