This is a first post on migrating from datamapper 0.2.5 to 0.9. 0.9 is a complete rewrite of datamapper so careful attention needs to be applied for this migration. ShellShadow is in production with 0.2.5 and I hope to get a new release out on 0.9 very soon so I’ll be posting my experiences as I go.
The first thing I have encountered is a key difference in defining unique indexes.
In 0.2.5 ( or 0.3) you would write something like this:
class User < DataMapper::Base
property :email, String, :index => :unique
property :display_name, String, :index => :unique
which would produce SQL indexes (for postgres) as:
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"users_display_name_key" UNIQUE, btree (display_name)
"users_email_key" UNIQUE, btree (email)
"users_display_name_index" btree (display_name)
"users_email_index" btree (email)
doing a fairly straightforward conversion to datamapper 0.9 yields the following:
class User
include DataMapper::Resource
property :id, Integer, :serial => true
property :email, String, :index => :unique
property :display_name, String, :index => :unique
which generate these SQL indexes (postgres):
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"index_users_unique" btree (email, display_name)
This creates a single unique index on the combined fields email and display_name; not what I want. I assume this is quite possibly an intended effect as this is how combined key fields gets handled in the new dm 0.9. After a few minutes looking through the very clean datamapper 0.9 source, I find there a constraint type called unique_index. When I use this as follows:
class User
include DataMapper::Resource
property :id, Integer, :serial => true
property :email, String, :unique_index => true
property :display_name, String, :unique_index => true
I get indexes generated as:
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"unique_index_users_display_name" UNIQUE, btree (display_name)
"unique_index_users_email" UNIQUE, btree (email)
much better!!!

{ 1 comment… read it below or add one }
comment by John W Higgins:
There’s another little trick to the :unique_index concept – if you use a symbol as opposed to true then you can create multiple named indexes with multiple fields.
Extending your example slightly (but not realistically)….
class User
include DataMapper::Resource
property :id, Integer, :serial => true
property :email, String, :unique_index => true
property :display_name, String, :unique_index => :names
property :full_name, String, :unique_index => :names
property :address String, :unique_index => :bob
Will get indexes generated along the lines of…
Indexes:“users_pkey” PRIMARY KEY, btree (id)
“unique_index_users_names” UNIQUE, btree (display_name, full_name)
“unique_index_users_email” UNIQUE, btree (email) “unique_index_users_bob” UNIQUE, btree (address)