Skip to content
Browse files

Copyediting of the 'migrations' guide.

  • Loading branch information...
1 parent 07a1d64 commit 8ba1fc18e13c03966d411947180022c1730e81ff Andreas Scherer committed Feb 19, 2009
Showing with 22 additions and 22 deletions.
  1. +22 −22 railties/guides/source/migrations.textile
View
44 railties/guides/source/migrations.textile
@@ -55,7 +55,7 @@ class AddReceiveNewsletterToUsers < ActiveRecord::Migration
end
</ruby>
-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
+This migration adds a +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.
NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations.
@@ -70,9 +70,9 @@ Active Record provides methods that perform common data definition tasks in a da
* +change_table+
* +drop_table+
* +add_column+
-* +remove_column+
* +change_column+
* +rename_column+
+* +remove_column+
* +add_index+
* +remove_index+
@@ -82,19 +82,19 @@ On databases that support transactions with statements that change the schema (s
h4. What's in a name
-Migrations are stored in files in +db/migrate+, one for each migration class. The name of the file is of the form +YYYYMMDDHHMMSS_create_products.rb+, that is to say a UTC timestamp identifying the migration followed by an underscore followed by the name of the migration. The migration class' name must match (the camelcased version of) the latter part of the file name. For example +20080906120000_create_products.rb+ should define +CreateProducts+ and +20080906120001_add_details_to_products.rb+ should define +AddDetailsToProducts+. If you do feel the need to change the file name then you MUST update the name of the class inside or Rails will complain about a missing class.
+Migrations are stored in files in +db/migrate+, one for each migration class. The name of the file is of the form +YYYYMMDDHHMMSS_create_products.rb+, that is to say a UTC timestamp identifying the migration followed by an underscore followed by the name of the migration. The migration class' name must match (the camelcased version of) the latter part of the file name. For example +20080906120000_create_products.rb+ should define +CreateProducts+ and +20080906120001_add_details_to_products.rb+ should define +AddDetailsToProducts+. If you do feel the need to change the file name then you <em>have to</em> update the name of the class inside or Rails will complain about a missing class.
Internally Rails only uses the migration's number (the timestamp) to identify them. Prior to Rails 2.1 the migration number started at 1 and was incremented each time a migration was generated. With multiple developers it was easy for these to clash requiring you to rollback migrations and renumber them. With Rails 2.1 this is largely avoided by using the creation time of the migration to identify them. You can revert to the old numbering scheme by setting +config.active_record.timestamped_migrations+ to +false+ in +config/environment.rb+.
The combination of timestamps and recording which migrations have been run allows Rails to handle common situations that occur with multiple developers.
-For example Alice adds migrations +20080906120000+ and +20080906123000+ and Bob adds +20080906124500+ and runs it. Alice finishes her changes and checks in her migrations and Bob pulls down the latest changes. Rails knows that it has not run Alice's two migrations so +rake db:migrate+ would run them (even though Bob's migration with a later timestamp has been run), and similarly migrating down would not run their down methods.
+For example Alice adds migrations +20080906120000+ and +20080906123000+ and Bob adds +20080906124500+ and runs it. Alice finishes her changes and checks in her migrations and Bob pulls down the latest changes. Rails knows that it has not run Alice's two migrations so +rake db:migrate+ would run them (even though Bob's migration with a later timestamp has been run), and similarly migrating down would not run their +down+ methods.
-Of course this is no substitution for communication within the team, for example if Alice's migration removed a table that Bob's migration assumed the existence of then trouble will still occur.
+Of course this is no substitution for communication within the team. For example, if Alice's migration removed a table that Bob's migration assumed to exist, then trouble would certainly strike.
h4. Changing migrations
-Occasionally you will make a mistake while writing a migration. If you have already run the migration then you cannot just edit the migration and run the migration again: Rails thinks it has already run the migration and so will do nothing when you run +rake db:migrate+. You must rollback the migration (for example with +rake db:rollback+), edit your migration and then run +rake db:migrate+ to run the corrected version.
+Occasionally you will make a mistake when writing a migration. If you have already run the migration then you cannot just edit the migration and run the migration again: Rails thinks it has already run the migration and so will do nothing when you run +rake db:migrate+. You must rollback the migration (for example with +rake db:rollback+), edit your migration and then run +rake db:migrate+ to run the corrected version.
In general editing existing migrations is not a good idea: you will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or more generally which has not been propagated beyond your development machine) is relatively harmless. Just use some common sense.
@@ -150,8 +150,7 @@ class AddPartNumberToProducts < ActiveRecord::Migration
end
</ruby>
-If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromY" and is followed by a list of column names and types then a migration containing
-the appropriate add and remove column statements will be created.
+If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is followed by a list of column names and types then a migration containing the appropriate +add_column+ and +remove_column+ statements will be created.
<shell>
ruby script/generate migration AddPartNumberToProducts part_number:string
@@ -231,34 +230,35 @@ 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 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 (traditional) form looks like
<ruby>
create_table :products do |t|
t.column :name, :string, :null => false
end
</ruby>
-the second form, the so called "sexy" migrations, drops the somewhat redundant column method. Instead, the +string+, +integer+ etc. methods create a column of that type. Subsequent parameters are identical.
+the second form, the so called "sexy" migration, drops the somewhat redundant +column+ method. Instead, the +string+, +integer+, etc. methods create a column of that type. Subsequent parameters are the same.
<ruby>
create_table :products do |t|
t.string :name, :null => false
end
</ruby>
-By default +create_table+ will create a primary key called +id+. You can change the name of the primary key with the +:primary_key+ option (don't forget to update the corresponding model) or if you don't want a primary key at all (for example for a HABTM join table) you can pass +:id => false+. If you need to pass database specific options you can place an sql fragment in the +:options+ option. For example
+By default +create_table+ will create a primary key called +id+. You can change the name of the primary key with the +:primary_key+ option (don't forget to update the corresponding model) or if you don't want a primary key at all (for example for a HABTM join table) you can pass +:id => false+. If you need to pass database specific options you can place an SQL fragment in the +:options+ option. For example
<ruby>
create_table :products, :options => "ENGINE=BLACKHOLE" do |t|
t.string :name, :null => false
end
</ruby>
-Will append +ENGINE=BLACKHOLE+ to the SQL used to create the table (when using MySQL the default is +ENGINE=InnoDB+).
-The types Active Record supports are +:primary_key+, +:string+, +:text+, +:integer+, +:float+, +:decimal+, +:datetime+, +:timestamp+, +:time+, +:date+, +:binary+, +:boolean+.
+will append +ENGINE=BLACKHOLE+ to the SQL statement used to create the table (when using MySQL the default is +ENGINE=InnoDB+).
+
+The types supported by Active Record are +:primary_key+, +:string+, +:text+, +:integer+, +:float+, +:decimal+, +:datetime+, +:timestamp+, +:time+, +:date+, +:binary+, +:boolean+.
-These will be mapped onto an appropriate underlying database type, for example with MySQL +:string+ is mapped to +VARCHAR(255)+. You can create columns of types not supported by Active Record when using the non sexy syntax, for example
+These will be mapped onto an appropriate underlying database type, for example with MySQL +:string+ is mapped to +VARCHAR(255)+. You can create columns of types not supported by Active Record when using the non-sexy syntax, for example
<ruby>
create_table :products do |t|
@@ -270,7 +270,7 @@ This may however hinder portability to other databases.
h4. Changing tables
-A close cousin of +create_table+ is +change_table+. Used for changing existing tables, it is used in a similar fashion to +create_table+ but the object yielded to the block knows more tricks. For example
+A close cousin of +create_table+ is +change_table+, used for changing existing tables. It is used in a similar fashion to +create_table+ but the object yielded to the block knows more tricks. For example
<ruby>
change_table :products do |t|
@@ -280,7 +280,7 @@ change_table :products do |t|
t.rename :upccode, :upc_code
end
</ruby>
-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
+removes the +description+ and +name+ columns, creates a +part_number+ column and adds an index on it. Finally it renames the +upccode+ column. This is the same as doing
<ruby>
remove_column :products, :description
@@ -301,7 +301,7 @@ create_table :products do |t|
t.timestamps
end
</ruby>
-will create a new products table with those two columns whereas
+will create a new products table with those two columns (plus the +id+ column) whereas
<ruby>
change_table :products do |t|
@@ -318,7 +318,7 @@ create_table :products do |t|
end
</ruby>
-will create a +category_id+ column of the appropriate type. Note that you pass the model name, not the column name. Active Record adds the +_id+ for you. If you have polymorphic belongs_to associations then +references+ will add both of the columns required:
+will create a +category_id+ column of the appropriate type. Note that you pass the model name, not the column name. Active Record adds the +_id+ for you. If you have polymorphic +belongs_to+ associations then +references+ will add both of the columns required:
<ruby>
create_table :products do |t|
@@ -335,7 +335,7 @@ For more details and examples of individual methods check the API documentation,
h4. Writing your down method
-The +down+ method of your migration should revert the transformations done by the +up+ method. In other words the database should be unchanged if you do an +up+ followed by a +down+. For example if you create a table in the up you should drop it in the +down+ method. It is wise to do things in precisely the reverse order to in the +up+ method. For example
+The +down+ method of your migration should revert the transformations done by the +up+ method. In other words the database schema should be unchanged if you do an +up+ followed by a +down+. For example if you create a table in the +up+ method you should drop it in the +down+ method. It is wise to do things in precisely the reverse order to in the +up+ method. For example
<ruby>
class ExampleMigration < ActiveRecord::Migration
@@ -564,7 +564,7 @@ ActiveRecord::Schema.define(:version => 20080906171750) do
end
</ruby>
-In many ways this is exactly what it is. This file is created by inspecting the database and expressing its structure using +create_table+, +add_index+ and so on. Because this is database independent it could be loaded into any database that Active Record supports. This could be very useful if you were to distribute an application that is able to run against multiple databases.
+In many ways this is exactly what it is. This file is created by inspecting the database and expressing its structure using +create_table+, +add_index+, and so on. Because this is database independent it could be loaded into any database that Active Record supports. This could be very useful if you were to distribute an application that is able to run against multiple databases.
There is however a trade-off: +db/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+.
@@ -574,11 +574,11 @@ By definition this will be a perfect copy of the database's structure but this w
h4. Schema dumps and source control
-Because they are the authoritative source for your database schema, it is strongly recommended that you check them into source control.
+Because schema dumps are the authoritative source for your database schema, it is strongly recommended that you check them into source control.
h3. 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.
+The Active Record way claims 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. Like anything which operates at the application level these cannot guarantee referential integrity and so some people augment them with foreign key constraints.

0 comments on commit 8ba1fc1

Please sign in to comment.
Something went wrong with that request. Please try again.