Permalink
Browse files

Final batch of corrections

  • Loading branch information...
1 parent 7b9a5c1 commit 25fd841fe0f1d6f43019595a06aef6d825f5f4d1 @fcheung fcheung committed Sep 13, 2008
@@ -41,7 +41,7 @@ end
------------------------
This migration adds an `receive_newsletter` column to the `users` table. We want it to default to `false` for new users, but existing users are considered
-to have already opted in, so we use the User model to set the flag to true for existing users.
+to have already opted in, so we use the User model to set the flag to `true` for existing users.
NOTE: Some <<models,caveats>> apply to using models in your migrations.
@@ -63,7 +63,7 @@ Active Record provides methods that perform common data definition tasks in a da
If you need to perform tasks specific to your database (for example create a <<foreign_key,foreign key>> constraint) then the `execute` function allows you to execute arbitrary SQL. A migration is just a regular Ruby class so you're not limited to these functions. For example after adding a column you could
write code to set the value of that column for existing records (if necessary using your models).
-On databases that support transactions with statements that change the schema, migrations are wrapped in a transaction. If the database does not support this (for example Mysql and SQLite) then when a migration fails the parts of it that succeeded will not be rolled back. You will have to unpick the changes that were made by hand.
+On databases that support transactions with statements that change the schema (such as PostgreSQL), migrations are wrapped in a transaction. If the database does not support this (for example MySQL and SQLite) then when a migration fails the parts of it that succeeded will not be rolled back. You will have to unpick the changes that were made by hand.
=== What's in a name ===
@@ -2,6 +2,6 @@
== Active Record and Referential Integrity ==
The Active Record way is that intelligence belongs in your models, not in the database. As such features such as triggers or foreign key constraints, which push some of that intelligence back into the database are not heavily used.
-Validations such as `validates_uniqueness_of` are one way in which models can enforce data integrity. The `:dependent` option on associations allows models to automatically destroy child objects when the parent is destroyed. These cannot however guarantee referential integrity and so some people augment them with foreign key constraints.
+Validations such as `validates_uniqueness_of` are one way in which models can enforce data integrity. The `:dependent` option on associations allows models to automatically destroy child objects when the parent is destroyed. Like anything which operates at the application level these cannot guarantee referential integrity and so some people augment them with foreign key constraints.
-Although Active Record does not provide any tools for working directly with such features, the `execute` method can be used to execute arbitrary SQL. There are also a number of plugins such as http://agilewebdevelopment.com/plugins/search?search=redhillonrails[redhillonrails] which add foreign key support to Active Record (including support in `schema.rb`).
+Although Active Record does not provide any tools for working directly with such features, the `execute` method can be used to execute arbitrary SQL. There are also a number of plugins such as http://agilewebdevelopment.com/plugins/search?search=redhillonrails[redhillonrails] which add foreign key support to Active Record (including support for dumping foreign keys in `schema.rb`).
@@ -3,13 +3,13 @@ Migrations
Migrations are a convenient way for you to alter your database in a structured and organised manner. You could edit fragments of SQL by hand but you would then be responsible for telling other developers that they need to go and run it. You'd also have to keep track of which changes need to be run against the production machines next time you deploy. Active Record tracks which migrations have already been run so all you have to do is update your source and run `rake db:migrate`. Active Record will work out which migrations should be run.
-Migrations also allow you to describe these transformations using Ruby. The great thing about this is that (like most of Active Record's functionality) it's database independent, you don't need to worry about the precise syntax of CREATE TABLE any more that you worry about variations on SELECT * (you can drop down to raw SQL for database specific features). For example you could use SQLite3 in development, but MySQL in production.
+Migrations also allow you to describe these transformations using Ruby. The great thing about this is that (like most of Active Record's functionality) it is database independent: you don't need to worry about the precise syntax of CREATE TABLE any more that you worry about variations on SELECT * (you can drop down to raw SQL for database specific features). For example you could use SQLite3 in development, but MySQL in production.
You'll learn all about migrations including:
* The generators you can use to create them
* The methods Active Record provides to manipulate your database
-* The rake tasks that manipulate them
+* The Rake tasks that manipulate them
* How they relate to `schema.rb`
include::anatomy_of_a_migration.txt[]
@@ -5,37 +5,47 @@ Rails provides a set of rake tasks to work with migrations which boils down to r
If you specify a target version, Active Record will run the required migrations (up or down) until it has reached the specified version. The
version is the numerical prefix on the migration's filename. For example to migrate to version 20080906120000 run
-`rake db:migrate VERSION=20080906120000`
+------------------------------------
+rake db:migrate VERSION=20080906120000
+------------------------------------
If this is greater than the current version (i.e. it is migrating upwards) this will run the `up` method on all migrations up to and including 20080906120000, if migrating downwards this will run the `down` method on all the migrations down to, but not including, 20080906120000.
-Almost all the functionality provided by other rake tasks could be done using `db:migrate` but would be more tedious (partly because of the long version numbers you would have to lookup and enter).
-
=== Rolling back ===
-A common task is to rollback the last migration, for example if you made a mistake in it and wish to correct it. Rather than track down the version number associated with the previous migration you can run
+A common task is to rollback the last migration, for example if you made a mistake in it and wish to correct it. Rather than tracking down the version number associated with the previous migration you can run
-`rake db:rollback`
+------------------
+rake db:rollback
+------------------
This will run the `down` method from the latest migration. If you need to undo several migrations you can provide a `STEP` parameter:
-`rake db:rollback STEP=3`
+------------------
+rake db:rollback STEP=3
+------------------
will run the `down` method fron the last 3 migrations.
The `db:migrate:redo` task is a shortcut for doing a rollback and then migrating back up again. As with the `db:rollback` task you can use the `STEP` parameter if you need to go more than one version back, for example
-`rake db:migrate:redo STEP=3`
+------------------
+rake db:migrate:redo STEP=3
+------------------
+
+Neither of these Rake tasks do anything you could not do with `db:migrate`, they are simply more convenient since you do not need to explicitly specify the version to migrate to.
Lastly, the `db:reset` task will drop the database, recreate it and load the current schema into it.
-NOTE: this is not the same as running all the migrations - see the section on <<schema,schema.rb>>).
+NOTE: This is not the same as running all the migrations - see the section on <<schema,schema.rb>>.
=== Being Specific ===
If you need to run a specific migration up or down the `db:migrate:up` and `db:migrate:down` tasks will do that. Just specify the appropriate version and the corresponding migration will have its `up` or `down` method invoked, for example
-`rake db:migrate:up VERSION=20080906120000`
+------------------
+rake db:migrate:up VERSION=20080906120000
+------------------
will run the `up` method from the 20080906120000 migration. These tasks check whether the migration has already run, so for example `db:migrate:up VERSION=20080906120000` will do nothing if Active Record believes that 20080906120000 has already been run.
@@ -5,7 +5,7 @@ Migrations, mighty as they may be, are not the authoritative source for your dat
There is no need (and it is error prone) to deploy a new instance of an app by replaying the entire migration history. It is much simpler and faster to just load into the database a description of the current schema.
-For example, this is how the test database is created: the current development database is dumped (either to `schema.rb` or `development.sql`) and then loaded.
+For example, this is how the test database is created: the current development database is dumped (either to `schema.rb` or `development.sql`) and then loaded into the test database.
Schema files are also useful if want a quick look at what attributes an Active Record object has. This information is not in the model's code and is frequently spread across several migrations but is all summed up in the schema file. The http://agilewebdevelopment.com/plugins/annotate_models[annotate_models] plugin, which automatically adds (and updates) comments at the top of each model summarising the schema, may also be of interest.
@@ -37,7 +37,7 @@ In many ways this is exactly what it is. This file is created by inspecting the
There is however a trade-off: `schema.rb` cannot express database specific items such as foreign key constraints, triggers or stored procedures. While in a migration you can execute custom SQL statements, the schema dumper cannot reconstitute those statements from the database. If you are using features like this then you should set the schema format to `:sql`.
-Instead of using Active Record's schema dumper the database's structure will be dumped using a tool specific to that database (via the `db:structure:dump` rake task) into `db/#\{RAILS_ENV\}_structure.sql`. For example for PostgreSQL the `pg_dump` utility is used and for MySQL this file will contain the output of SHOW CREATE TABLE for the various tables. Loading this schema is simply a question of executing the SQL statements contained inside.
+Instead of using Active Record's schema dumper the database's structure will be dumped using a tool specific to that database (via the `db:structure:dump` Rake task) into `db/#\{RAILS_ENV\}_structure.sql`. For example for PostgreSQL the `pg_dump` utility is used and for MySQL this file will contain the output of SHOW CREATE TABLE for the various tables. Loading this schema is simply a question of executing the SQL statements contained inside.
By definition this will be a perfect copy of the database's structure but this will usually prevent loading the schema into a database other than the one used to create it.
@@ -1,6 +1,8 @@
[[models]]
== Using Models In Your Migrations ==
-When creating or updating data in a migration it is often tempting to use one of your models. After all they exist to provide easy access to the underlying data. This can be done but some caution should be observed. Consider for example a migration that uses the Product model to update a row in the corresponding table. Alice later updates the Product model, adding a new column and a validation on it. Bob comes back from holiday, updates the source and runs outstanding migrations with `rake db:migrate`, including the one that used the Product model. When the migration runs the source is up to date and so the Product model has the validation added by Alice. The database however is still old and so does not have that column and an error ensues.
+When creating or updating data in a migration it is often tempting to use one of your models. After all they exist to provide easy access to the underlying data. This can be done but some caution should be observed.
+
+Consider for example a migration that uses the Product model to update a row in the corresponding table. Alice later updates the Product model, adding a new column and a validation on it. Bob comes back from holiday, updates the source and runs outstanding migrations with `rake db:migrate`, including the one that used the Product model. When the migration runs the source is up to date and so the Product model has the validation added by Alice. The database however is still old and so does not have that column and an error ensues because that validation is on a column that does not yet exist.
Frequently I just want to update rows in the database without writing out the SQL by hand: I'm not using anything specific to the model. One pattern for this is to define a copy of the model inside the migration itself, for example:
@@ -14,7 +14,7 @@ end
---------------------
which creates a `products` table with a column called `name` (and as discussed below, an implicit `id` column).
-The object yielded to the block allows you create columns on the table. There are two ways of the doing this. The first looks like
+The object yielded to the block allows you create columns on the table. There are two ways of doing this. The first looks like
[source, ruby]
---------------------
@@ -40,7 +40,7 @@ create_table :products, :options => "ENGINE=InnoDB" do |t|
t.string :name, :null => false
end
---------------------
-Will append `ENGINE=InnoDB` to the sql used to create the table (This is Rails' default when using MySQL).
+Will append `ENGINE=InnoDB` to the sql used to create the table (this is Rails' default when using MySQL).
The types Active Record supports are `:primary_key`, `:string`, `:text`, `:integer`, `:float`, `:decimal`, `:datetime`, `:timestamp`, `:time`, `:date`, `:binary`, `:boolean`.
@@ -68,7 +68,7 @@ change_table :products do |t|
t.rename :upccode, :upc_code
end
---------------------
-removes the description column, creates a part_number column and adds an index on it. This is the same as doing
+removes the `description` column, creates a `part_number` column and adds an index on it. Finally it renames the `upccode` column. This is the same as doing
[source, ruby]
---------------------
@@ -120,11 +120,11 @@ end
---------------------
will add an `attachment_id` column and a string `attachment_type` column with a default value of 'Photo'.
-NOTE: The `references` helper does not actually create <<foreign_key,foreign key>> constraints for you. You will need to use `execute` for that.
+NOTE: The `references` helper does not actually create foreign key constraints for you. You will need to use `execute` for that or a plugin that adds <<foreign_key,foreign key support>>.
If the helpers provided by Active Record aren't enough you can use the `execute` function to execute arbitrary SQL.
-For more details and examples of individual methods check the API documentation.
+For more details and examples of individual methods check the API documentation, in particular the documentation for http://api.rubyonrails.com/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html[ActiveRecord::ConnectionAdapters::SchemaStatements] (which provides the methods available in the `up` and `down` methods), http://api.rubyonrails.com/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html[ActiveRecord::ConnectionAdapters::TableDefinition] (which provides the methods available on the object yielded by `create_table`) and http://api.rubyonrails.com/classes/ActiveRecord/ConnectionAdapters/Table.html[ActiveRecord::ConnectionAdapters::Table] (which provides the methods available on the object yielded by `change_table`).
=== Writing your down method ===

0 comments on commit 25fd841

Please sign in to comment.