Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1
Version Control | 307

should always pull thedb/migratedirectory from the version control system immedi-
ately before generating a migration. Conversely, these migrations should be checked
in as soon as is practical after generation, so all developers have access.


Unfortunately, when using branches, it is not generally possible to publish every
schema change across all branches. If it were, a simple solution would be to set up a
shared migrations directory in the version control repository, and import it via asvn:
externals(or equivalent) declaration. In most cases, schema changes to separate
branches must be kept separate; at the least, production databases should not be pol-
luted with database changes for new features. So, another solution must be found.
There are several schools of thought on how this should work.


The simplest solution, which is probably the most popular, is Courtenay’s Independent
Migrations plugin (http://blog.caboo.se/articles/2007/3/27/independent-migrations-plugin).
The basic assumption is that migrations which are created in different branches or
working copies are logically independent of each other. (If this assumption doesn’t
hold, you will have problems when merging, no matter how you slice it.)


After installing the plugin, simply tag your independent migrations as such by inherit-
ing fromActiveRecord::IndependentMigration rather thanActiveRecord::Migration.


class AddFeature < ActiveRecord::IndependentMigration
# ...
end

Multiple independent migrations will then be applied concurrently, so migrations
can be merged without renumbering. However, this does not eliminate the need to
migrate down and back up when several migrations have been applied to a database;
the plugin will not search old version numbers (older than the current version) for
new migrations.


My solution, Subverted Migrations,*is more complicated, but it aims to be as trans-
parent as possible once you understand it. As the name suggests, it only works with
Subversion. The intent is to synchronize version numbers across all branches. That
way, all developers and all branches have the same view of the migrations that have
been applied project-wide. It applies two changes to the Rails version-numbering
mechanism:



  • It serializes version numbers across all branches by scanning the Subversion
    repository for all branches to find a free version number.

  • It changes the semantics of theschema_versiontable: rather than being the num-
    ber of the latest-applied migration, the schema version is a list of migrations that
    have been applied to the database. When older changes from other branches are
    merged in, a simplerake db:migrateapplies them without the need to migrate
    down and up.


*http://www.bradediger.com/blog/2006/11/subverted_migrations.html

Free download pdf