railties 3.1.12 → 3.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (210) hide show
  1. data/CHANGELOG.md +2292 -41
  2. data/README.rdoc +14 -5
  3. data/bin/rails +7 -0
  4. data/guides/code/getting_started/Gemfile +27 -0
  5. data/guides/code/getting_started/README.rdoc +261 -0
  6. data/guides/code/getting_started/Rakefile +7 -0
  7. data/guides/code/getting_started/app/assets/images/rails.png +0 -0
  8. data/guides/code/getting_started/app/assets/javascripts/application.js +9 -0
  9. data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +3 -0
  10. data/guides/code/getting_started/app/assets/javascripts/home.js.coffee +3 -0
  11. data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +3 -0
  12. data/guides/code/getting_started/app/assets/stylesheets/application.css +7 -0
  13. data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +3 -0
  14. data/guides/code/getting_started/app/assets/stylesheets/home.css.scss +3 -0
  15. data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +3 -0
  16. data/guides/code/getting_started/app/assets/stylesheets/scaffolds.css.scss +56 -0
  17. data/guides/code/getting_started/app/controllers/application_controller.rb +3 -0
  18. data/guides/code/getting_started/app/controllers/comments_controller.rb +16 -0
  19. data/guides/code/getting_started/app/controllers/home_controller.rb +5 -0
  20. data/guides/code/getting_started/app/controllers/posts_controller.rb +84 -0
  21. data/guides/code/getting_started/app/helpers/application_helper.rb +2 -0
  22. data/guides/code/getting_started/app/helpers/comments_helper.rb +2 -0
  23. data/guides/code/getting_started/app/helpers/home_helper.rb +2 -0
  24. data/guides/code/getting_started/app/helpers/posts_helper.rb +5 -0
  25. data/guides/code/getting_started/app/models/comment.rb +3 -0
  26. data/guides/code/getting_started/app/models/post.rb +11 -0
  27. data/guides/code/getting_started/app/models/tag.rb +3 -0
  28. data/guides/code/getting_started/app/views/comments/_comment.html.erb +15 -0
  29. data/guides/code/getting_started/app/views/comments/_form.html.erb +13 -0
  30. data/guides/code/getting_started/app/views/home/index.html.erb +2 -0
  31. data/guides/code/getting_started/app/views/layouts/application.html.erb +14 -0
  32. data/guides/code/getting_started/app/views/posts/_form.html.erb +32 -0
  33. data/guides/code/getting_started/app/views/posts/edit.html.erb +6 -0
  34. data/guides/code/getting_started/app/views/posts/index.html.erb +27 -0
  35. data/guides/code/getting_started/app/views/posts/new.html.erb +5 -0
  36. data/guides/code/getting_started/app/views/posts/show.html.erb +31 -0
  37. data/guides/code/getting_started/app/views/tags/_form.html.erb +12 -0
  38. data/guides/code/getting_started/config.ru +4 -0
  39. data/guides/code/getting_started/config/application.rb +53 -0
  40. data/guides/code/getting_started/config/boot.rb +6 -0
  41. data/guides/code/getting_started/config/database.yml +25 -0
  42. data/guides/code/getting_started/config/environment.rb +5 -0
  43. data/guides/code/getting_started/config/environments/development.rb +37 -0
  44. data/guides/code/getting_started/config/environments/production.rb +67 -0
  45. data/guides/code/getting_started/config/environments/test.rb +37 -0
  46. data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +7 -0
  47. data/guides/code/getting_started/config/initializers/inflections.rb +10 -0
  48. data/guides/code/getting_started/config/initializers/mime_types.rb +5 -0
  49. data/guides/code/getting_started/config/initializers/secret_token.rb +7 -0
  50. data/guides/code/getting_started/config/initializers/session_store.rb +8 -0
  51. data/guides/code/getting_started/config/initializers/wrap_parameters.rb +14 -0
  52. data/guides/code/getting_started/config/locales/en.yml +5 -0
  53. data/guides/code/getting_started/config/routes.rb +64 -0
  54. data/guides/code/getting_started/db/migrate/20110901012504_create_posts.rb +11 -0
  55. data/guides/code/getting_started/db/migrate/20110901012815_create_comments.rb +12 -0
  56. data/guides/code/getting_started/db/migrate/20110901013701_create_tags.rb +11 -0
  57. data/guides/code/getting_started/db/schema.rb +43 -0
  58. data/guides/code/getting_started/db/seeds.rb +7 -0
  59. data/guides/code/getting_started/doc/README_FOR_APP +2 -0
  60. data/guides/code/getting_started/public/404.html +26 -0
  61. data/guides/code/getting_started/public/422.html +26 -0
  62. data/guides/code/getting_started/public/500.html +26 -0
  63. data/guides/code/getting_started/public/favicon.ico +0 -0
  64. data/guides/code/getting_started/public/robots.txt +5 -0
  65. data/guides/code/getting_started/script/rails +6 -0
  66. data/guides/code/getting_started/test/fixtures/comments.yml +11 -0
  67. data/guides/code/getting_started/test/fixtures/posts.yml +11 -0
  68. data/guides/code/getting_started/test/fixtures/tags.yml +9 -0
  69. data/guides/code/getting_started/test/functional/comments_controller_test.rb +7 -0
  70. data/guides/code/getting_started/test/functional/home_controller_test.rb +9 -0
  71. data/guides/code/getting_started/test/functional/posts_controller_test.rb +49 -0
  72. data/guides/code/getting_started/test/performance/browsing_test.rb +12 -0
  73. data/guides/code/getting_started/test/test_helper.rb +13 -0
  74. data/guides/code/getting_started/test/unit/comment_test.rb +7 -0
  75. data/guides/code/getting_started/test/unit/helpers/comments_helper_test.rb +4 -0
  76. data/guides/code/getting_started/test/unit/helpers/home_helper_test.rb +4 -0
  77. data/guides/code/getting_started/test/unit/helpers/posts_helper_test.rb +4 -0
  78. data/guides/code/getting_started/test/unit/post_test.rb +7 -0
  79. data/guides/code/getting_started/test/unit/tag_test.rb +7 -0
  80. data/guides/rails_guides/generator.rb +2 -1
  81. data/guides/source/3_0_release_notes.textile +2 -2
  82. data/guides/source/3_1_release_notes.textile +3 -110
  83. data/guides/source/action_controller_overview.textile +11 -13
  84. data/guides/source/action_mailer_basics.textile +7 -18
  85. data/guides/source/action_view_overview.textile +78 -9
  86. data/guides/source/active_model_basics.textile +205 -0
  87. data/guides/source/active_record_basics.textile +31 -31
  88. data/guides/source/active_record_querying.textile +288 -67
  89. data/guides/source/active_record_validations_callbacks.textile +69 -75
  90. data/guides/source/active_resource_basics.textile +48 -2
  91. data/guides/source/active_support_core_extensions.textile +145 -24
  92. data/guides/source/ajax_on_rails.textile +65 -7
  93. data/guides/source/api_documentation_guidelines.textile +0 -6
  94. data/guides/source/asset_pipeline.textile +2 -2
  95. data/guides/source/association_basics.textile +25 -34
  96. data/guides/source/caching_with_rails.textile +12 -17
  97. data/guides/source/command_line.textile +29 -19
  98. data/guides/source/configuring.textile +40 -18
  99. data/guides/source/contributing_to_ruby_on_rails.textile +11 -18
  100. data/guides/source/debugging_rails_applications.textile +10 -21
  101. data/guides/source/engines.textile +618 -0
  102. data/guides/source/form_helpers.textile +1 -12
  103. data/guides/source/generators.textile +9 -11
  104. data/guides/source/getting_started.textile +152 -152
  105. data/guides/source/i18n.textile +4 -5
  106. data/guides/source/index.html.erb +0 -1
  107. data/guides/source/initialization.textile +26 -26
  108. data/guides/source/layouts_and_rendering.textile +97 -61
  109. data/guides/source/migrations.textile +380 -161
  110. data/guides/source/performance_testing.textile +4 -10
  111. data/guides/source/plugins.textile +11 -19
  112. data/guides/source/rails_application_templates.textile +12 -4
  113. data/guides/source/rails_on_rack.textile +25 -19
  114. data/guides/source/routing.textile +6 -13
  115. data/guides/source/ruby_on_rails_guides_guidelines.textile +0 -5
  116. data/guides/source/security.textile +11 -15
  117. data/guides/source/testing.textile +1 -9
  118. data/lib/rails/application.rb +107 -42
  119. data/lib/rails/application/bootstrap.rb +12 -11
  120. data/lib/rails/application/configuration.rb +27 -21
  121. data/lib/rails/application/finisher.rb +40 -17
  122. data/lib/rails/application/route_inspector.rb +75 -0
  123. data/lib/rails/application/routes_reloader.rb +15 -4
  124. data/lib/rails/code_statistics.rb +16 -5
  125. data/lib/rails/commands.rb +6 -5
  126. data/lib/rails/commands/application.rb +8 -1
  127. data/lib/rails/commands/console.rb +2 -0
  128. data/lib/rails/commands/dbconsole.rb +2 -2
  129. data/lib/rails/commands/destroy.rb +0 -2
  130. data/lib/rails/commands/generate.rb +3 -3
  131. data/lib/rails/commands/plugin.rb +161 -159
  132. data/lib/rails/commands/plugin_new.rb +3 -2
  133. data/lib/rails/commands/runner.rb +4 -0
  134. data/lib/rails/console/app.rb +26 -22
  135. data/lib/rails/console/helpers.rb +9 -5
  136. data/lib/rails/engine.rb +70 -34
  137. data/lib/rails/engine/commands.rb +39 -0
  138. data/lib/rails/engine/configuration.rb +1 -1
  139. data/lib/rails/generators.rb +3 -14
  140. data/lib/rails/generators/actions.rb +36 -9
  141. data/lib/rails/generators/app_base.rb +34 -38
  142. data/lib/rails/generators/base.rb +4 -4
  143. data/lib/rails/generators/generated_attribute.rb +1 -1
  144. data/lib/rails/generators/named_base.rb +1 -3
  145. data/lib/rails/generators/rails/app/USAGE +6 -0
  146. data/lib/rails/generators/rails/app/app_generator.rb +6 -2
  147. data/lib/rails/generators/rails/app/templates/Gemfile +4 -3
  148. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +9 -3
  149. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +11 -5
  150. data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
  151. data/lib/rails/generators/rails/app/templates/app/models/.empty_directory +0 -0
  152. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +1 -1
  153. data/lib/rails/generators/rails/app/templates/config/application.rb +11 -0
  154. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +1 -1
  155. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +1 -1
  156. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +10 -1
  157. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +10 -1
  158. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +6 -6
  159. data/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb +5 -0
  160. data/lib/rails/generators/rails/app/templates/config/routes.rb +1 -1
  161. data/lib/rails/generators/rails/app/templates/public/500.html +0 -1
  162. data/lib/rails/generators/rails/app/templates/public/index.html +1 -1
  163. data/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory +0 -0
  164. data/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory +0 -0
  165. data/lib/rails/generators/rails/app/templates/test/functional/.empty_directory +0 -0
  166. data/lib/rails/generators/rails/app/templates/test/integration/.empty_directory +0 -0
  167. data/lib/rails/generators/rails/app/templates/test/unit/.empty_directory +0 -0
  168. data/lib/rails/generators/rails/controller/templates/controller.rb +1 -1
  169. data/lib/rails/generators/rails/generator/templates/templates/.empty_directory +0 -0
  170. data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +17 -5
  171. data/lib/rails/generators/rails/plugin_new/templates/Rakefile +1 -0
  172. data/lib/rails/generators/rails/plugin_new/templates/app/mailers/.empty_directory +0 -0
  173. data/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory +0 -0
  174. data/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt +1 -1
  175. data/lib/rails/generators/rails/plugin_new/templates/gitignore +4 -3
  176. data/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb +1 -1
  177. data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +1 -1
  178. data/lib/rails/generators/rails/plugin_new/templates/script/rails.tt +5 -3
  179. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +2 -2
  180. data/lib/rails/generators/rails/task/USAGE +9 -0
  181. data/lib/rails/generators/rails/task/task_generator.rb +12 -0
  182. data/lib/rails/generators/rails/task/templates/task.rb +8 -0
  183. data/lib/rails/generators/resource_helpers.rb +3 -3
  184. data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +0 -2
  185. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +4 -4
  186. data/lib/rails/paths.rb +11 -38
  187. data/lib/rails/rack/debugger.rb +3 -4
  188. data/lib/rails/rack/logger.rb +26 -12
  189. data/lib/rails/railtie.rb +6 -1
  190. data/lib/rails/railtie/configuration.rb +12 -5
  191. data/lib/rails/source_annotation_extractor.rb +12 -10
  192. data/lib/rails/tasks/documentation.rake +3 -1
  193. data/lib/rails/tasks/engine.rake +1 -0
  194. data/lib/rails/tasks/misc.rake +1 -1
  195. data/lib/rails/tasks/routes.rake +3 -23
  196. data/lib/rails/test_help.rb +1 -2
  197. data/lib/rails/test_unit/testing.rake +8 -4
  198. data/lib/rails/version.rb +3 -3
  199. metadata +131 -61
  200. checksums.yaml +0 -7
  201. data/lib/rails/generators/rails/plugin/USAGE +0 -13
  202. data/lib/rails/generators/rails/plugin/plugin_generator.rb +0 -54
  203. data/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt +0 -20
  204. data/lib/rails/generators/rails/plugin/templates/README.tt +0 -13
  205. data/lib/rails/generators/rails/plugin/templates/Rakefile.tt +0 -23
  206. data/lib/rails/generators/rails/plugin/templates/init.rb +0 -1
  207. data/lib/rails/generators/rails/plugin/templates/install.rb +0 -1
  208. data/lib/rails/generators/rails/plugin/templates/lib/%file_name%.rb.tt +0 -1
  209. data/lib/rails/generators/rails/plugin/templates/lib/tasks/%file_name%_tasks.rake.tt +0 -4
  210. data/lib/rails/generators/rails/plugin/templates/uninstall.rb +0 -1
@@ -1,12 +1,24 @@
1
1
  h2. Migrations
2
2
 
3
- Migrations are a convenient way for you to alter your database in a structured and organized 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 them. You'd also have to keep track of which changes need to be run against the production machines next time you deploy.
4
-
5
- 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. It will also update your +db/schema.rb+ file to match the structure of your database.
6
-
7
- 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 than 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.
8
-
9
- You'll learn all about migrations including:
3
+ Migrations are a convenient way for you to alter your database in a structured
4
+ and organized manner. You could edit fragments of SQL by hand but you would then
5
+ be responsible for telling other developers that they need to go and run them.
6
+ You'd also have to keep track of which changes need to be run against the
7
+ production machines next time you deploy.
8
+
9
+ Active Record tracks which migrations have already been run so all you have to
10
+ do is update your source and run +rake db:migrate+. Active Record will work out
11
+ which migrations should be run. It will also update your +db/schema.rb+ file to
12
+ match the structure of your database.
13
+
14
+ Migrations also allow you to describe these transformations using Ruby. The
15
+ great thing about this is that (like most of Active Record's functionality) it
16
+ is database independent: you don't need to worry about the precise syntax of
17
+ +CREATE TABLE+ any more than you worry about variations on +SELECT *+ (you can
18
+ drop down to raw SQL for database specific features). For example you could use
19
+ SQLite3 in development, but MySQL in production.
20
+
21
+ In this guide, you'll learn all about migrations including:
10
22
 
11
23
  * The generators you can use to create them
12
24
  * The methods Active Record provides to manipulate your database
@@ -17,7 +29,8 @@ endprologue.
17
29
 
18
30
  h3. Anatomy of a Migration
19
31
 
20
- Before we dive into the details of a migration, here are a few examples of the sorts of things you can do:
32
+ Before we dive into the details of a migration, here are a few examples of the
33
+ sorts of things you can do:
21
34
 
22
35
  <ruby>
23
36
  class CreateProducts < ActiveRecord::Migration
@@ -36,9 +49,15 @@ class CreateProducts < ActiveRecord::Migration
36
49
  end
37
50
  </ruby>
38
51
 
39
- This migration adds a table called +products+ with a string column called +name+ and a text column called +description+. A primary key column called +id+ will also be added, however since this is the default we do not need to ask for this. The timestamp columns +created_at+ and +updated_at+ which Active Record populates automatically will also be added. Reversing this migration is as simple as dropping the table.
52
+ This migration adds a table called +products+ with a string column called +name+
53
+ and a text column called +description+. A primary key column called +id+ will
54
+ also be added, however since this is the default we do not need to ask for this.
55
+ The timestamp columns +created_at+ and +updated_at+ which Active Record
56
+ populates automatically will also be added. Reversing this migration is as
57
+ simple as dropping the table.
40
58
 
41
- Migrations are not limited to changing the schema. You can also use them to fix bad data in the database or populate new fields:
59
+ Migrations are not limited to changing the schema. You can also use them to fix
60
+ bad data in the database or populate new fields:
42
61
 
43
62
  <ruby>
44
63
  class AddReceiveNewsletterToUsers < ActiveRecord::Migration
@@ -55,12 +74,18 @@ class AddReceiveNewsletterToUsers < ActiveRecord::Migration
55
74
  end
56
75
  </ruby>
57
76
 
58
- NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations.
77
+ NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in
78
+ your migrations.
59
79
 
60
- 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
61
- to have already opted in, so we use the User model to set the flag to +true+ for existing users.
80
+ This migration adds a +receive_newsletter+ column to the +users+ table. We want
81
+ it to default to +false+ for new users, but existing users are considered to
82
+ have already opted in, so we use the User model to set the flag to +true+ for
83
+ existing users.
62
84
 
63
- Rails 3.1 makes migrations smarter by providing a new <tt>change</tt> method. This method is preferred for writing constructive migrations (adding columns or tables). The migration knows how to migrate your database and reverse it when the migration is rolled back without the need to write a separate +down+ method.
85
+ Rails 3.1 makes migrations smarter by providing a new <tt>change</tt> method.
86
+ This method is preferred for writing constructive migrations (adding columns or
87
+ tables). The migration knows how to migrate your database and reverse it when
88
+ the migration is rolled back without the need to write a separate +down+ method.
64
89
 
65
90
  <ruby>
66
91
  class CreateProducts < ActiveRecord::Migration
@@ -77,64 +102,111 @@ end
77
102
 
78
103
  h4. Migrations are Classes
79
104
 
80
- A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements two methods: +up+ (perform the required transformations) and +down+ (revert them).
105
+ A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements
106
+ two methods: +up+ (perform the required transformations) and +down+ (revert
107
+ them).
81
108
 
82
- Active Record provides methods that perform common data definition tasks in a database independent way (you'll read about them in detail later):
109
+ Active Record provides methods that perform common data definition tasks in a
110
+ database independent way (you'll read about them in detail later):
83
111
 
84
- * +create_table+
85
- * +change_table+
86
- * +drop_table+
87
112
  * +add_column+
113
+ * +add_index+
88
114
  * +change_column+
89
- * +rename_column+
115
+ * +change_table+
116
+ * +create_table+
117
+ * +drop_table+
90
118
  * +remove_column+
91
- * +add_index+
92
119
  * +remove_index+
120
+ * +rename_column+
93
121
 
94
- If you need to perform tasks specific to your database (for example create a "foreign key":#active-record-and-referential-integrity 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).
122
+ If you need to perform tasks specific to your database (for example create a
123
+ "foreign key":#active-record-and-referential-integrity constraint) then the
124
+ +execute+ method allows you to execute arbitrary SQL. A migration is just a
125
+ regular Ruby class so you're not limited to these functions. For example after
126
+ adding a column you could write code to set the value of that column for
127
+ existing records (if necessary using your models).
95
128
 
96
- On databases that support transactions with statements that change the schema (such as PostgreSQL or SQLite3), migrations are wrapped in a transaction. If the database does not support this (for example MySQL) 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.
129
+ On databases that support transactions with statements that change the schema
130
+ (such as PostgreSQL or SQLite3), migrations are wrapped in a transaction. If the
131
+ database does not support this (for example MySQL) then when a migration fails
132
+ the parts of it that succeeded will not be rolled back. You will have to rollback
133
+ the changes that were made by hand.
97
134
 
98
135
  h4. What's in a Name
99
136
 
100
- 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 name of the migration class (CamelCased version) should match 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.
101
-
102
- 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 adding the following line to +config/application.rb+.
137
+ Migrations are stored as files in the +db/migrate+ directory, one for each
138
+ migration class. The name of the file is of the form
139
+ +YYYYMMDDHHMMSS_create_products.rb+, that is to say a UTC timestamp
140
+ identifying the migration followed by an underscore followed by the name
141
+ of the migration. The name of the migration class (CamelCased version)
142
+ should match the latter part of the file name. For example
143
+ +20080906120000_create_products.rb+ should define class +CreateProducts+ and
144
+ +20080906120001_add_details_to_products.rb+ should define
145
+ +AddDetailsToProducts+. If you do feel the need to change the file name then you
146
+ <em>have to</em> update the name of the class inside or Rails will complain
147
+ about a missing class.
148
+
149
+ Internally Rails only uses the migration's number (the timestamp) to identify
150
+ them. Prior to Rails 2.1 the migration number started at 1 and was incremented
151
+ each time a migration was generated. With multiple developers it was easy for
152
+ these to clash requiring you to rollback migrations and renumber them. With
153
+ Rails 2.1+ this is largely avoided by using the creation time of the migration
154
+ to identify them. You can revert to the old numbering scheme by adding the
155
+ following line to +config/application.rb+.
103
156
 
104
157
  <ruby>
105
158
  config.active_record.timestamped_migrations = false
106
159
  </ruby>
107
160
 
108
- The combination of timestamps and recording which migrations have been run allows Rails to handle common situations that occur with multiple developers.
161
+ The combination of timestamps and recording which migrations have been run
162
+ allows Rails to handle common situations that occur with multiple developers.
109
163
 
110
- 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.
164
+ For example Alice adds migrations +20080906120000+ and +20080906123000+ and Bob
165
+ adds +20080906124500+ and runs it. Alice finishes her changes and checks in her
166
+ migrations and Bob pulls down the latest changes. When Bob runs +rake db:migrate+,
167
+ Rails knows that it has not run Alice's two migrations so it executes the +up+ method for each migration.
111
168
 
112
- 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.
169
+ Of course this is no substitution for communication within the team. For
170
+ example, if Alice's migration removed a table that Bob's migration assumed to
171
+ exist, then trouble would certainly strike.
113
172
 
114
173
  h4. Changing Migrations
115
174
 
116
- 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.
175
+ Occasionally you will make a mistake when writing a migration. If you have
176
+ already run the migration then you cannot just edit the migration and run the
177
+ migration again: Rails thinks it has already run the migration and so will do
178
+ nothing when you run +rake db:migrate+. You must rollback the migration (for
179
+ example with +rake db:rollback+), edit your migration and then run +rake db:migrate+ to run the corrected version.
117
180
 
118
- 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.
181
+ In general editing existing migrations is not a good idea: you will be creating
182
+ extra work for yourself and your co-workers and cause major headaches if the
183
+ existing version of the migration has already been run on production machines.
184
+ Instead, you should write a new migration that performs the changes you require.
185
+ Editing a freshly generated migration that has not yet been committed to source
186
+ control (or, more generally, which has not been propagated beyond your
187
+ development machine) is relatively harmless.
119
188
 
120
189
  h4. Supported Types
121
190
 
122
- Active Record supports the following types:
191
+ Active Record supports the following database column types:
123
192
 
193
+ * +:binary+
194
+ * +:boolean+
195
+ * +:date+
196
+ * +:datetime+
197
+ * +:decimal+
198
+ * +:float+
199
+ * +:integer+
124
200
  * +:primary_key+
125
201
  * +:string+
126
202
  * +:text+
127
- * +:integer+
128
- * +:float+
129
- * +:decimal+
130
- * +:datetime+
131
- * +:timestamp+
132
203
  * +:time+
133
- * +:date+
134
- * +:binary+
135
- * +:boolean+
204
+ * +:timestamp+
136
205
 
137
- 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
206
+ These will be mapped onto an appropriate underlying database type. For example,
207
+ with MySQL the type +:string+ is mapped to +VARCHAR(255)+. You can create
208
+ columns of types not supported by Active Record when using the non-sexy syntax,
209
+ for example
138
210
 
139
211
  <ruby>
140
212
  create_table :products do |t|
@@ -148,7 +220,10 @@ h3. Creating a Migration
148
220
 
149
221
  h4. Creating a Model
150
222
 
151
- The model and scaffold generators will create migrations appropriate for adding a new model. This migration will already contain instructions for creating the relevant table. If you tell Rails what columns you want then statements for adding those will also be created. For example, running
223
+ The model and scaffold generators will create migrations appropriate for adding
224
+ a new model. This migration will already contain instructions for creating the
225
+ relevant table. If you tell Rails what columns you want, then statements for
226
+ adding these columns will also be created. For example, running
152
227
 
153
228
  <shell>
154
229
  $ rails generate model Product name:string description:text
@@ -169,12 +244,15 @@ class CreateProducts < ActiveRecord::Migration
169
244
  end
170
245
  </ruby>
171
246
 
172
- You can append as many column name/type pairs as you want. By default +t.timestamps+ (which creates the +updated_at+ and +created_at+ columns that
173
- are automatically populated by Active Record) will be added for you.
247
+ You can append as many column name/type pairs as you want. By default, the
248
+ generated migration will include +t.timestamps+ (which creates the
249
+ +updated_at+ and +created_at+ columns that are automatically populated
250
+ by Active Record).
174
251
 
175
252
  h4. Creating a Standalone Migration
176
253
 
177
- If you are creating migrations for other purposes (for example to add a column to an existing table) then you can use the migration generator:
254
+ If you are creating migrations for other purposes (for example to add a column
255
+ to an existing table) then you can also use the migration generator:
178
256
 
179
257
  <shell>
180
258
  $ rails generate migration AddPartNumberToProducts
@@ -189,7 +267,9 @@ class AddPartNumberToProducts < ActiveRecord::Migration
189
267
  end
190
268
  </ruby>
191
269
 
192
- 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.
270
+ If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is
271
+ followed by a list of column names and types then a migration containing the
272
+ appropriate +add_column+ and +remove_column+ statements will be created.
193
273
 
194
274
  <shell>
195
275
  $ rails generate migration AddPartNumberToProducts part_number:string
@@ -242,17 +322,23 @@ class AddDetailsToProducts < ActiveRecord::Migration
242
322
  end
243
323
  </ruby>
244
324
 
245
- As always, what has been generated for you is just a starting point. You can add or remove from it as you see fit.
325
+ As always, what has been generated for you is just a starting point. You can add
326
+ or remove from it as you see fit by editing the
327
+ db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb file.
246
328
 
247
- NOTE: The generated migration file for destructive migrations will still be old-style using the +up+ and +down+ methods. This is because Rails doesn't know the original data types defined when you made the original changes.
329
+ NOTE: The generated migration file for destructive migrations will still be
330
+ old-style using the +up+ and +down+ methods. This is because Rails needs to know
331
+ the original data types defined when you made the original changes.
248
332
 
249
333
  h3. Writing a Migration
250
334
 
251
- Once you have created your migration using one of the generators it's time to get to work!
335
+ Once you have created your migration using one of the generators it's time to
336
+ get to work!
252
337
 
253
338
  h4. Creating a Table
254
339
 
255
- Migration method +create_table+ will be one of your workhorses. A typical use would be
340
+ Migration method +create_table+ will be one of your workhorses. A typical use
341
+ would be
256
342
 
257
343
  <ruby>
258
344
  create_table :products do |t|
@@ -260,9 +346,11 @@ create_table :products do |t|
260
346
  end
261
347
  </ruby>
262
348
 
263
- which creates a +products+ table with a column called +name+ (and as discussed below, an implicit +id+ column).
349
+ which creates a +products+ table with a column called +name+ (and as discussed
350
+ below, an implicit +id+ column).
264
351
 
265
- The object yielded to the block allows you to create columns on the table. There are two ways of doing this: The first (traditional) form looks like
352
+ The object yielded to the block allows you to create columns on the table. There
353
+ are two ways of doing it. The first (traditional) form looks like
266
354
 
267
355
  <ruby>
268
356
  create_table :products do |t|
@@ -270,7 +358,9 @@ create_table :products do |t|
270
358
  end
271
359
  </ruby>
272
360
 
273
- 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.
361
+ The second form, the so called "sexy" migration, drops the somewhat redundant
362
+ +column+ method. Instead, the +string+, +integer+, etc. methods create a column
363
+ of that type. Subsequent parameters are the same.
274
364
 
275
365
  <ruby>
276
366
  create_table :products do |t|
@@ -278,7 +368,12 @@ create_table :products do |t|
278
368
  end
279
369
  </ruby>
280
370
 
281
- 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
371
+ By default, +create_table+ will create a primary key called +id+. You can change
372
+ the name of the primary key with the +:primary_key+ option (don't forget to
373
+ update the corresponding model) or, if you don't want a primary key at all (for
374
+ example for a HABTM join table), you can pass the option +:id => false+. If you
375
+ need to pass database specific options you can place an SQL fragment in the
376
+ +:options+ option. For example,
282
377
 
283
378
  <ruby>
284
379
  create_table :products, :options => "ENGINE=BLACKHOLE" do |t|
@@ -286,11 +381,14 @@ create_table :products, :options => "ENGINE=BLACKHOLE" do |t|
286
381
  end
287
382
  </ruby>
288
383
 
289
- will append +ENGINE=BLACKHOLE+ to the SQL statement used to create the table (when using MySQL the default is +ENGINE=InnoDB+).
384
+ will append +ENGINE=BLACKHOLE+ to the SQL statement used to create the table
385
+ (when using MySQL, the default is +ENGINE=InnoDB+).
290
386
 
291
387
  h4. Changing Tables
292
388
 
293
- 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
389
+ A close cousin of +create_table+ is +change_table+, used for changing existing
390
+ tables. It is used in a similar fashion to +create_table+ but the object yielded
391
+ to the block knows more tricks. For example
294
392
 
295
393
  <ruby>
296
394
  change_table :products do |t|
@@ -301,28 +399,23 @@ change_table :products do |t|
301
399
  end
302
400
  </ruby>
303
401
 
304
- 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
305
-
306
- <ruby>
307
- remove_column :products, :description
308
- remove_column :products, :name
309
- add_column :products, :part_number, :string
310
- add_index :products, :part_number
311
- rename_column :products, :upccode, :upc_code
312
- </ruby>
313
-
314
- You don't have to keep repeating the table name and it groups all the statements related to modifying one particular table. The individual transformation names are also shorter, for example +remove_column+ becomes just +remove+ and +add_index+ becomes just +index+.
402
+ removes the +description+ and +name+ columns, creates a +part_number+ string
403
+ column and adds an index on it. Finally it renames the +upccode+ column.
315
404
 
316
405
  h4. Special Helpers
317
406
 
318
- Active Record provides some shortcuts for common functionality. It is for example very common to add both the +created_at+ and +updated_at+ columns and so there is a method that does exactly that:
407
+ Active Record provides some shortcuts for common functionality. It is for
408
+ example very common to add both the +created_at+ and +updated_at+ columns and so
409
+ there is a method that does exactly that:
319
410
 
320
411
  <ruby>
321
412
  create_table :products do |t|
322
413
  t.timestamps
323
414
  end
324
415
  </ruby>
325
- will create a new products table with those two columns (plus the +id+ column) whereas
416
+
417
+ will create a new products table with those two columns (plus the +id+ column)
418
+ whereas
326
419
 
327
420
  <ruby>
328
421
  change_table :products do |t|
@@ -331,7 +424,8 @@ end
331
424
  </ruby>
332
425
  adds those columns to an existing table.
333
426
 
334
- The other helper is called +references+ (also available as +belongs_to+). In its simplest form it just adds some readability
427
+ Another helper is called +references+ (also available as +belongs_to+). In its
428
+ simplest form it just adds some readability.
335
429
 
336
430
  <ruby>
337
431
  create_table :products do |t|
@@ -339,24 +433,42 @@ create_table :products do |t|
339
433
  end
340
434
  </ruby>
341
435
 
342
- 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:
436
+ will create a +category_id+ column of the appropriate type. Note that you pass
437
+ the model name, not the column name. Active Record adds the +_id+ for you. If
438
+ you have polymorphic +belongs_to+ associations then +references+ will add both
439
+ of the columns required:
343
440
 
344
441
  <ruby>
345
442
  create_table :products do |t|
346
443
  t.references :attachment, :polymorphic => {:default => 'Photo'}
347
444
  end
348
445
  </ruby>
349
- will add an +attachment_id+ column and a string +attachment_type+ column with a default value of 'Photo'.
350
446
 
351
- 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 support":#active-record-and-referential-integrity.
447
+ will add an +attachment_id+ column and a string +attachment_type+ column with
448
+ a default value of 'Photo'.
449
+
450
+ NOTE: The +references+ helper does not actually create foreign key constraints
451
+ for you. You will need to use +execute+ or a plugin that adds "foreign key
452
+ support":#active-record-and-referential-integrity.
352
453
 
353
- If the helpers provided by Active Record aren't enough you can use the +execute+ function to execute arbitrary SQL.
454
+ If the helpers provided by Active Record aren't enough you can use the +execute+
455
+ method to execute arbitrary SQL.
354
456
 
355
- For more details and examples of individual methods check the API documentation, in particular the documentation for "<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html (which provides the methods available in the +up+ and +down+ methods), "<tt>ActiveRecord::ConnectionAdapters::TableDefinition</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html (which provides the methods available on the object yielded by +create_table+) and "<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html (which provides the methods available on the object yielded by +change_table+).
457
+ For more details and examples of individual methods, check the API documentation,
458
+ in particular the documentation for
459
+ "<tt>ActiveRecord::ConnectionAdapters::SchemaStatements</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html
460
+ (which provides the methods available in the +up+ and +down+ methods),
461
+ "<tt>ActiveRecord::ConnectionAdapters::TableDefinition</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html
462
+ (which provides the methods available on the object yielded by +create_table+)
463
+ and
464
+ "<tt>ActiveRecord::ConnectionAdapters::Table</tt>":http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html
465
+ (which provides the methods available on the object yielded by +change_table+).
356
466
 
357
- h4. Writing Your +change+ Method
467
+ h4. Using the +change+ Method
358
468
 
359
- The +change+ method removes the need to write both +up+ and +down+ methods in those cases that Rails know how to revert the changes automatically. Currently, the +change+ method supports only these migration definitions:
469
+ The +change+ method removes the need to write both +up+ and +down+ methods in
470
+ those cases that Rails know how to revert the changes automatically. Currently,
471
+ the +change+ method supports only these migration definitions:
360
472
 
361
473
  * +add_column+
362
474
  * +add_index+
@@ -367,15 +479,20 @@ The +change+ method removes the need to write both +up+ and +down+ methods in th
367
479
  * +rename_index+
368
480
  * +rename_table+
369
481
 
370
- If you're going to use other methods, you'll have to write the +up+ and +down+ methods normally.
482
+ If you're going to need to use any other methods, you'll have to write the
483
+ +up+ and +down+ methods instead of using the +change+ method.
371
484
 
372
- h4. Writing Your +down+ Method
485
+ h4. Using the +up+/+down+ Methods
373
486
 
374
- 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
487
+ The +down+ method of your migration should revert the transformations done by
488
+ the +up+ method. In other words, the database schema should be unchanged if you
489
+ do an +up+ followed by a +down+. For example, if you create a table in the +up+
490
+ method, you should drop it in the +down+ method. It is wise to reverse the
491
+ transformations in precisely the reverse order they were made in the +up+
492
+ method. For example,
375
493
 
376
494
  <ruby>
377
495
  class ExampleMigration < ActiveRecord::Migration
378
-
379
496
  def up
380
497
  create_table :products do |t|
381
498
  t.references :category
@@ -387,47 +504,69 @@ class ExampleMigration < ActiveRecord::Migration
387
504
  FOREIGN KEY (category_id)
388
505
  REFERENCES categories(id)
389
506
  SQL
390
-
391
507
  add_column :users, :home_page_url, :string
392
-
393
508
  rename_column :users, :email, :email_address
394
509
  end
395
510
 
396
511
  def down
397
512
  rename_column :users, :email_address, :email
398
513
  remove_column :users, :home_page_url
399
- execute "ALTER TABLE products DROP FOREIGN KEY fk_products_categories"
514
+ execute <<-SQL
515
+ ALTER TABLE products
516
+ DROP FOREIGN KEY fk_products_categories
517
+ SQL
400
518
  drop_table :products
401
519
  end
402
520
  end
403
521
  </ruby>
404
522
 
405
- Sometimes your migration will do something which is just plain irreversible, for example it might destroy some data. In cases like those when you can't reverse the migration you can raise +ActiveRecord::IrreversibleMigration+ from your +down+ method. If someone tries to revert your migration an error message will be displayed saying that it can't be done.
523
+ Sometimes your migration will do something which is just plain irreversible; for
524
+ example, it might destroy some data. In such cases, you can raise
525
+ +ActiveRecord::IrreversibleMigration+ from your +down+ method. If someone tries
526
+ to revert your migration, an error message will be displayed saying that it
527
+ can't be done.
406
528
 
407
529
  h3. Running Migrations
408
530
 
409
- Rails provides a set of rake tasks to work with migrations which boils down to running certain sets of migrations. The very first migration related rake task you use will probably be +db:migrate+. In its most basic form it just runs the +up+ method for all the migrations that have not yet been run. If there are no such migrations it exits.
531
+ Rails provides a set of rake tasks to work with migrations which boil down to
532
+ running certain sets of migrations.
533
+
534
+ The very first migration related rake task you will use will probably be
535
+ +rake db:migrate+. In its most basic form it just runs the +up+ or +change+
536
+ method for all the migrations that have not yet been run. If there are
537
+ no such migrations, it exits. It will run these migrations in order based
538
+ on the date of the migration.
410
539
 
411
- Note that running the +db:migrate+ also invokes the +db:schema:dump+ task, which will update your db/schema.rb file to match the structure of your database.
540
+ Note that running the +db:migrate+ also invokes the +db:schema:dump+ task, which
541
+ will update your db/schema.rb file to match the structure of your database.
412
542
 
413
- If you specify a target version, Active Record will run the required migrations (up or down) until it has reached the specified version. The
414
- version is the numerical prefix on the migration's filename. For example to migrate to version 20080906120000 run
543
+ If you specify a target version, Active Record will run the required migrations
544
+ (up, down or change) until it has reached the specified version. The version
545
+ is the numerical prefix on the migration's filename. For example, to migrate
546
+ to version 20080906120000 run
415
547
 
416
548
  <shell>
417
549
  $ rake db:migrate VERSION=20080906120000
418
550
  </shell>
419
551
 
420
- 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.
552
+ If version 20080906120000 is greater than the current version (i.e., it is
553
+ migrating upwards), this will run the +up+ method on all migrations up to and
554
+ including 20080906120000, and will not execute any later migrations. If
555
+ migrating downwards, this will run the +down+ method on all the migrations
556
+ down to, but not including, 20080906120000.
421
557
 
422
558
  h4. Rolling Back
423
559
 
424
- 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
560
+ A common task is to rollback the last migration, for example if you made a
561
+ mistake in it and wish to correct it. Rather than tracking down the version
562
+ number associated with the previous migration you can run
425
563
 
426
564
  <shell>
427
565
  $ rake db:rollback
428
566
  </shell>
429
567
 
430
- This will run the +down+ method from the latest migration. If you need to undo several migrations you can provide a +STEP+ parameter:
568
+ This will run the +down+ method from the latest migration. If you need to undo
569
+ several migrations you can provide a +STEP+ parameter:
431
570
 
432
571
  <shell>
433
572
  $ rake db:rollback STEP=3
@@ -435,46 +574,65 @@ $ rake db:rollback STEP=3
435
574
 
436
575
  will run the +down+ method from the last 3 migrations.
437
576
 
438
- 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
577
+ The +db:migrate:redo+ task is a shortcut for doing a rollback and then migrating
578
+ back up again. As with the +db:rollback+ task, you can use the +STEP+ parameter
579
+ if you need to go more than one version back, for example
439
580
 
440
581
  <shell>
441
582
  $ rake db:migrate:redo STEP=3
442
583
  </shell>
443
584
 
444
- 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.
585
+ Neither of these Rake tasks do anything you could not do with +db:migrate+. They
586
+ are simply more convenient, since you do not need to explicitly specify the
587
+ version to migrate to.
445
588
 
446
- Lastly, the +db:reset+ task will drop the database, recreate it and load the current schema into it.
589
+ h4. Resetting the database
447
590
 
448
- NOTE: This is not the same as running all the migrations - see the section on "schema.rb":#schema-dumping-and-you.
591
+ The +rake db:reset+ task will drop the database, recreate it and load the
592
+ current schema into it.
449
593
 
450
- h4. Being Specific
594
+ NOTE: This is not the same as running all the migrations - see the section on
595
+ "schema.rb":#schema-dumping-and-you.
451
596
 
452
- 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
597
+ h4. Running specific migrations
598
+
599
+ If you need to run a specific migration up or down, the +db:migrate:up+ and
600
+ +db:migrate:down+ tasks will do that. Just specify the appropriate version and
601
+ the corresponding migration will have its +up+ or +down+ method invoked, for
602
+ example,
453
603
 
454
604
  <shell>
455
605
  $ rake db:migrate:up VERSION=20080906120000
456
606
  </shell>
457
607
 
458
- 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.
608
+ will run the +up+ method from the 20080906120000 migration. These tasks still
609
+ check whether the migration has already run, so for example +db:migrate:up
610
+ VERSION=20080906120000+ will do nothing if Active Record believes that
611
+ 20080906120000 has already been run.
459
612
 
460
- h4. Being Talkative
613
+ h4. Changing the output of running migrations
461
614
 
462
- By default migrations tell you exactly what they're doing and how long it took. A migration creating a table and adding an index might produce output like this
615
+ By default migrations tell you exactly what they're doing and how long it took.
616
+ A migration creating a table and adding an index might produce output like this
463
617
 
464
618
  <shell>
465
- 20080906170109 CreateProducts: migrating
619
+ == CreateProducts: migrating =================================================
466
620
  -- create_table(:products)
467
- -> 0.0021s
468
- -- add_index(:products, :name)
469
- -> 0.0026s
470
- 20080906170109 CreateProducts: migrated (0.0059s)
621
+ -> 0.0028s
622
+ == CreateProducts: migrated (0.0028s) ========================================
471
623
  </shell>
472
624
 
473
- Several methods are provided that allow you to control all this:
625
+ Several methods are provided in migrations that allow you to control all this:
474
626
 
475
- * +suppress_messages+ takes a block as an argument and suppresses any output generated by the block.
476
- * +say+ takes a message argument and outputs it as is. A second boolean argument can be passed to specify whether to indent or not.
477
- * +say_with_time+ outputs text along with how long it took to run its block. If the block returns an integer it assumes it is the number of rows affected.
627
+ |_.Method |_.Purpose|
628
+ |suppress_messages |Takes a block as an argument and suppresses any output
629
+ generated by the block.|
630
+ |say |Takes a message argument and outputs it as is. A second
631
+ boolean argument can be passed to specify whether to
632
+ indent or not.|
633
+ |say_with_time |Outputs text along with how long it took to run its
634
+ block. If the block returns an integer it assumes it
635
+ is the number of rows affected.|
478
636
 
479
637
  For example, this migration
480
638
 
@@ -502,37 +660,46 @@ end
502
660
  generates the following output
503
661
 
504
662
  <shell>
505
- 20080906170109 CreateProducts: migrating
506
- Created a table
663
+ == CreateProducts: migrating =================================================
664
+ -- Created a table
507
665
  -> and an index!
508
- Waiting for a while
509
- -> 10.0001s
666
+ -- Waiting for a while
667
+ -> 10.0013s
510
668
  -> 250 rows
511
- 20080906170109 CreateProducts: migrated (10.0097s)
669
+ == CreateProducts: migrated (10.0054s) =======================================
512
670
  </shell>
513
671
 
514
- If you just want Active Record to shut up then running +rake db:migrate VERBOSE=false+ will suppress all output.
672
+ If you want Active Record to not output anything, then running +rake db:migrate
673
+ VERBOSE=false+ will suppress all output.
515
674
 
516
675
  h3. Using Models in Your Migrations
517
676
 
518
- 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.
677
+ When creating or updating data in a migration it is often tempting to use one of
678
+ your models. After all, they exist to provide easy access to the underlying
679
+ data. This can be done, but some caution should be observed.
519
680
 
520
- For example, problems occur when the model uses database columns which are (1) not currently in the database and (2) will be created by this or a subsequent migration.
681
+ For example, problems occur when the model uses database columns which are (1)
682
+ not currently in the database and (2) will be created by this or a subsequent
683
+ migration.
521
684
 
522
- Consider this example, where Alice and Bob are working on the same code base which contains a +Product+ model:
685
+ Consider this example, where Alice and Bob are working on the same code base
686
+ which contains a +Product+ model:
523
687
 
524
688
  Bob goes on vacation.
525
689
 
526
- Alice creates a migration for the +products+ table which adds a new column and initializes it.
527
- She also adds a validation to the Product model for the new column.
690
+ Alice creates a migration for the +products+ table which adds a new column and
691
+ initializes it. She also adds a validation to the +Product+ model for the new
692
+ column.
528
693
 
529
694
  <ruby>
530
695
  # db/migrate/20100513121110_add_flag_to_product.rb
531
696
 
532
697
  class AddFlagToProduct < ActiveRecord::Migration
533
698
  def change
534
- add_column :products, :flag, :int
535
- Product.all.each { |f| f.update_attributes!(:flag => 'false') }
699
+ add_column :products, :flag, :boolean
700
+ Product.all.each do |product|
701
+ product.update_attributes!(:flag => 'false')
702
+ end
536
703
  end
537
704
  end
538
705
  </ruby>
@@ -545,7 +712,9 @@ class Product < ActiveRecord::Base
545
712
  end
546
713
  </ruby>
547
714
 
548
- Alice adds a second migration which adds and initializes another column to the +products+ table and also adds a validation to the Product model for the new column.
715
+ Alice adds a second migration which adds and initializes another column to the
716
+ +products+ table and also adds a validation to the +Product+ model for the new
717
+ column.
549
718
 
550
719
  <ruby>
551
720
  # db/migrate/20100515121110_add_fuzz_to_product.rb
@@ -553,7 +722,9 @@ Alice adds a second migration which adds and initializes another column to the +
553
722
  class AddFuzzToProduct < ActiveRecord::Migration
554
723
  def change
555
724
  add_column :products, :fuzz, :string
556
- Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
725
+ Product.all.each do |product|
726
+ product.update_attributes! :fuzz => 'fuzzy'
727
+ end
557
728
  end
558
729
  end
559
730
  </ruby>
@@ -570,10 +741,14 @@ Both migrations work for Alice.
570
741
 
571
742
  Bob comes back from vacation and:
572
743
 
573
- # updates the source - which contains both migrations and the latests version of the Product model.
574
- # runs outstanding migrations with +rake db:migrate+, which includes the one that updates the +Product+ model.
744
+ # Updates the source - which contains both migrations and the latests version of
745
+ the Product model.
746
+ # Runs outstanding migrations with +rake db:migrate+, which
747
+ includes the one that updates the +Product+ model.
575
748
 
576
- The migration crashes because when the model attempts to save, it tries to validate the second added column, which is not in the database when the _first_ migration runs.
749
+ The migration crashes because when the model attempts to save, it tries to
750
+ validate the second added column, which is not in the database when the _first_
751
+ migration runs:
577
752
 
578
753
  <plain>
579
754
  rake aborted!
@@ -582,9 +757,12 @@ An error has occurred, this and all later migrations canceled:
582
757
  undefined method `fuzz' for #<Product:0x000001049b14a0>
583
758
  </plain>
584
759
 
585
- A fix for this is to create a local model within the migration. This keeps rails from running the validations, so that the migrations run to completion.
760
+ A fix for this is to create a local model within the migration. This keeps rails
761
+ from running the validations, so that the migrations run to completion.
586
762
 
587
- When using a faux model, it's a good idea to call +Product.reset_column_information+ to refresh the ActiveRecord cache for the Product model prior to updating data in the database.
763
+ When using a faux model, it's a good idea to call
764
+ +Product.reset_column_information+ to refresh the +ActiveRecord+ cache for the
765
+ +Product+ model prior to updating data in the database.
588
766
 
589
767
  If Alice had done this instead, there would have been no problem:
590
768
 
@@ -596,9 +774,11 @@ class AddFlagToProduct < ActiveRecord::Migration
596
774
  end
597
775
 
598
776
  def change
599
- add_column :products, :flag, :int
777
+ add_column :products, :flag, :integer
600
778
  Product.reset_column_information
601
- Product.all.each { |f| f.update_attributes!(:flag => false) }
779
+ Product.all.each do |product|
780
+ product.update_attributes!(:flag => false)
781
+ end
602
782
  end
603
783
  end
604
784
  </ruby>
@@ -609,32 +789,50 @@ end
609
789
  class AddFuzzToProduct < ActiveRecord::Migration
610
790
  class Product < ActiveRecord::Base
611
791
  end
792
+
612
793
  def change
613
794
  add_column :products, :fuzz, :string
614
795
  Product.reset_column_information
615
- Product.all.each { |f| f.update_attributes! :fuzz => 'fuzzy' }
796
+ Product.all.each do |product|
797
+ product.update_attributes!(:fuzz => 'fuzzy')
798
+ end
616
799
  end
617
800
  end
618
801
  </ruby>
619
802
 
620
-
621
803
  h3. Schema Dumping and You
622
804
 
623
805
  h4. What are Schema Files for?
624
806
 
625
- Migrations, mighty as they may be, are not the authoritative source for your database schema. That role falls to either +db/schema.rb+ or an SQL file which Active Record generates by examining the database. They are not designed to be edited, they just represent the current state of the database.
807
+ Migrations, mighty as they may be, are not the authoritative source for your
808
+ database schema. That role falls to either +db/schema.rb+ or an SQL file which
809
+ Active Record generates by examining the database. They are not designed to be
810
+ edited, they just represent the current state of the database.
626
811
 
627
- 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.
812
+ There is no need (and it is error prone) to deploy a new instance of an app by
813
+ replaying the entire migration history. It is much simpler and faster to just
814
+ load into the database a description of the current schema.
628
815
 
629
- For example, this is how the test database is created: the current development database is dumped (either to +db/schema.rb+ or +db/development.sql+) and then loaded into the test database.
816
+ For example, this is how the test database is created: the current development
817
+ database is dumped (either to +db/schema.rb+ or +db/development.sql+) and then
818
+ loaded into the test database.
630
819
 
631
- Schema files are also useful if you 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 "annotate_models":http://agilewebdevelopment.com/plugins/annotate_models plugin, which automatically adds (and updates) comments at the top of each model summarizing the schema, may also be of interest.
820
+ Schema files are also useful if you want a quick look at what attributes an
821
+ Active Record object has. This information is not in the model's code and is
822
+ frequently spread across several migrations, but the information is nicely
823
+ summed up in the schema file. The
824
+ "annotate_models":https://github.com/ctran/annotate_models gem automatically
825
+ adds and updates comments at the top of each model summarizing the schema if
826
+ you desire that functionality.
632
827
 
633
828
  h4. Types of Schema Dumps
634
829
 
635
- There are two ways to dump the schema. This is set in +config/application.rb+ by the +config.active_record.schema_format+ setting, which may be either +:sql+ or +:ruby+.
830
+ There are two ways to dump the schema. This is set in +config/application.rb+ by
831
+ the +config.active_record.schema_format+ setting, which may be either +:sql+ or
832
+ +:ruby+.
636
833
 
637
- If +:ruby+ is selected then the schema is stored in +db/schema.rb+. If you look at this file you'll find that it looks an awful lot like one very big migration:
834
+ If +:ruby+ is selected then the schema is stored in +db/schema.rb+. If you look
835
+ at this file you'll find that it looks an awful lot like one very big migration:
638
836
 
639
837
  <ruby>
640
838
  ActiveRecord::Schema.define(:version => 20080906171750) do
@@ -646,36 +844,57 @@ ActiveRecord::Schema.define(:version => 20080906171750) do
646
844
 
647
845
  create_table "products", :force => true do |t|
648
846
  t.string "name"
649
- t.text "description"
847
+ t.text "description"
650
848
  t.datetime "created_at"
651
849
  t.datetime "updated_at"
652
- t.string "part_number"
850
+ t.string "part_number"
653
851
  end
654
852
  end
655
853
  </ruby>
656
854
 
657
- 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.
658
-
659
- 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+.
660
-
661
- 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.
662
-
663
- 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.
855
+ In many ways this is exactly what it is. This file is created by inspecting the
856
+ database and expressing its structure using +create_table+, +add_index+, and so
857
+ on. Because this is database-independent, it could be loaded into any database
858
+ that Active Record supports. This could be very useful if you were to distribute
859
+ an application that is able to run against multiple databases.
860
+
861
+ There is however a trade-off: +db/schema.rb+ cannot express database specific
862
+ items such as foreign key constraints, triggers, or stored procedures. While in
863
+ a migration you can execute custom SQL statements, the schema dumper cannot
864
+ reconstitute those statements from the database. If you are using features like
865
+ this, then you should set the schema format to +:sql+.
866
+
867
+ Instead of using Active Record's schema dumper, the database's structure will be
868
+ dumped using a tool specific to the database (via the +db:structure:dump+ Rake task)
869
+ into +db/structure.sql+. For example, for the PostgreSQL RDBMS, the
870
+ +pg_dump+ utility is used. For MySQL, this file will contain the output of +SHOW
871
+ CREATE TABLE+ for the various tables. Loading these schemas is simply a question
872
+ of executing the SQL statements they contain. By definition, this will create a
873
+ perfect copy of the database's structure. Using the +:sql+ schema format will,
874
+ however, prevent loading the schema into a RDBMS other than the one used to
875
+ create it.
664
876
 
665
877
  h4. Schema Dumps and Source Control
666
878
 
667
- Because schema dumps are the authoritative source for your database schema, it is strongly recommended that you check them into source control.
879
+ Because schema dumps are the authoritative source for your database schema, it
880
+ is strongly recommended that you check them into source control.
668
881
 
669
882
  h3. Active Record and Referential Integrity
670
883
 
671
- 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.
672
-
673
- Validations such as +validates :foreign_key, :uniqueness => true+ 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.
674
-
675
- 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 "foreign_key_migrations":https://github.com/harukizaemon/redhillonrails/tree/master/foreign_key_migrations/ which add foreign key support to Active Record (including support for dumping foreign keys in +db/schema.rb+).
676
-
677
- h3. Changelog
678
-
679
- * April 26, 2011: change generated +up+ and +down+ methods to +change+ method, and describe detail about +change+ method by "Prem Sichanugrist":http://sikachu.com
680
- * July 15, 2010: minor typos corrected by "Jaime Iniesta":http://jaimeiniesta.com
681
- * September 14, 2008: initial version by "Frederick Cheung":credits.html#fcheung
884
+ The Active Record way claims that intelligence belongs in your models, not in
885
+ the database. As such, features such as triggers or foreign key constraints,
886
+ which push some of that intelligence back into the database, are not heavily
887
+ used.
888
+
889
+ Validations such as +validates :foreign_key, :uniqueness => true+ are one way in
890
+ which models can enforce data integrity. The +:dependent+ option on associations
891
+ allows models to automatically destroy child objects when the parent is
892
+ destroyed. Like anything which operates at the application level, these cannot
893
+ guarantee referential integrity and so some people augment them with foreign key
894
+ constraints in the database.
895
+
896
+ Although Active Record does not provide any tools for working directly with such
897
+ features, the +execute+ method can be used to execute arbitrary SQL. You could
898
+ also use some plugin like "foreigner":https://github.com/matthuhiggins/foreigner
899
+ which add foreign key support to Active Record (including support for dumping
900
+ foreign keys in +db/schema.rb+).