Created
July 26, 2008 02:04
-
-
Save carllerche/2576 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# NOTE, all names, syntax, etc... are just off the top of my head to illustrate | |
# the general idea. Don't take anything too literally. | |
# I just started a blank project with DataMapper. DM Migrations knows | |
# that the current production database is empty because no schema has been "committed". | |
# | |
# I then created a new model: | |
class User | |
include DataMapper::Resource | |
property :id, Serial | |
end | |
# DataMapper.auto_migrate! can run and creates a new table users with the ID property. | |
# A new migration file is also created named work_in_progress.rb with the following | |
# content: | |
migrate( | |
:from => table(:users).missing, | |
:to => table(:users).with(:id => Serial) | |
) do | |
create_table(:users) do |u| | |
u.column :id, Serial | |
end | |
end | |
# I now decided that I want a username property and change the file: | |
class User | |
include DataMapper::Resource | |
property :id, Serial | |
property :username, String | |
end | |
# I run DataMapper.auto_migrate and the new column is created in development mode. | |
# DM still knows that I haven't committed so it goes ahead and modifies the current | |
# workign migration file to: | |
migrate( | |
:from => table(:users).missing, | |
:to => table(:users).with(:id => Serial, :username => String) | |
) do | |
create_table(:users) do |u| | |
u.column :id, Serial | |
u.column :username, String | |
end | |
end | |
# So, I decide I want to deploy my awesome application and type a command rake dm:commit | |
# and datamapper "freezes" the current work_in_progress.rb migration file for deployment. | |
# So, I deploy my app and decide that it sucks and I need to improve it. I also get John | |
# to help me. So, now there are two developers working on this awesome app. | |
# Ok, I decided that I needed to add a password field: | |
class User | |
include DataMapper::Resource | |
property :id, Serial | |
property :username, String | |
property :password, String | |
end | |
# I run auto_migrate. The old committed migration file is stashed somewhere and a new | |
# work_in_progress.rb migration is created with the following: | |
migrate( | |
# As you can see, this migration only requires a users table (with anything in it) | |
# as long as it can successfully add the password column | |
:from => table(:users), | |
:to => table(:users).with(:password => String) | |
) do | |
add_column :users, :password, String | |
end | |
# Ok, now John decides that he wants to remove :username (wtf??): | |
class User | |
include DataMapper::Resource | |
property :id, Serial | |
property :password, String | |
end | |
# And he commits and gets the following migrate file: | |
migrate( | |
# As you can see, this migration only requires a users table (with anything in it) | |
# as long as it can successfully add the password column | |
:from => table(:users).with(:username => String), | |
:to => table(:users) | |
) do | |
remove_column :users, :username | |
end | |
# Now here's a cool bit. What if I decide to change :password to an Integer and John | |
# decides to change :password to a Boolean? My migrate file would look like: | |
migrate( | |
:from => table(:users).with(:password => String), | |
:to => table(:users).with(:password => Integer) | |
) do | |
create_column :users, :new_password, Integer | |
execute "update users set new_password = integer(password);" | |
remove_column :users, :password | |
rename_column :users, :new_password, :password | |
end | |
# And John's migration file would look like: | |
migrate( | |
:from => table(:users).with(:password => String), | |
:to => table(:users).with(:password => Boolean) | |
) do | |
remove_column :users, :password | |
create_column :users, :password, Boolean | |
end | |
# DM Migrator would know that there is a conflict here and something would happen. | |
# CONCLUSION: | |
# The whole point is to make development easy with auto_migrate and then being able | |
# to safely get changes to production with some kind of smart migration files. This | |
# is still a really rough and crazy idea. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment