rails 3.2.22.5 → 4.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rails might be problematic. Click here for more details.

Files changed (281) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +77 -0
  3. data/guides/CHANGELOG.md +9 -0
  4. data/guides/Rakefile +77 -0
  5. data/guides/assets/images/belongs_to.png +0 -0
  6. data/guides/assets/images/book_icon.gif +0 -0
  7. data/guides/assets/images/bullet.gif +0 -0
  8. data/guides/assets/images/challenge.png +0 -0
  9. data/guides/assets/images/chapters_icon.gif +0 -0
  10. data/guides/assets/images/check_bullet.gif +0 -0
  11. data/guides/assets/images/credits_pic_blank.gif +0 -0
  12. data/guides/assets/images/csrf.png +0 -0
  13. data/guides/assets/images/edge_badge.png +0 -0
  14. data/guides/assets/images/favicon.ico +0 -0
  15. data/guides/assets/images/feature_tile.gif +0 -0
  16. data/guides/assets/images/footer_tile.gif +0 -0
  17. data/guides/assets/images/fxn.png +0 -0
  18. data/guides/assets/images/getting_started/confirm_dialog.png +0 -0
  19. data/guides/assets/images/getting_started/forbidden_attributes_for_new_post.png +0 -0
  20. data/guides/assets/images/getting_started/form_with_errors.png +0 -0
  21. data/guides/assets/images/getting_started/index_action_with_edit_link.png +0 -0
  22. data/guides/assets/images/getting_started/new_post.png +0 -0
  23. data/guides/assets/images/getting_started/post_with_comments.png +0 -0
  24. data/guides/assets/images/getting_started/routing_error_no_controller.png +0 -0
  25. data/guides/assets/images/getting_started/routing_error_no_route_matches.png +0 -0
  26. data/guides/assets/images/getting_started/show_action_for_posts.png +0 -0
  27. data/guides/assets/images/getting_started/template_is_missing_posts_new.png +0 -0
  28. data/guides/assets/images/getting_started/undefined_method_post_path.png +0 -0
  29. data/guides/assets/images/getting_started/unknown_action_create_for_posts.png +0 -0
  30. data/guides/assets/images/getting_started/unknown_action_new_for_posts.png +0 -0
  31. data/guides/assets/images/grey_bullet.gif +0 -0
  32. data/guides/assets/images/habtm.png +0 -0
  33. data/guides/assets/images/has_many.png +0 -0
  34. data/guides/assets/images/has_many_through.png +0 -0
  35. data/guides/assets/images/has_one.png +0 -0
  36. data/guides/assets/images/has_one_through.png +0 -0
  37. data/guides/assets/images/header_backdrop.png +0 -0
  38. data/guides/assets/images/header_tile.gif +0 -0
  39. data/guides/assets/images/i18n/demo_html_safe.png +0 -0
  40. data/guides/assets/images/i18n/demo_localized_pirate.png +0 -0
  41. data/guides/assets/images/i18n/demo_translated_en.png +0 -0
  42. data/guides/assets/images/i18n/demo_translated_pirate.png +0 -0
  43. data/guides/assets/images/i18n/demo_translation_missing.png +0 -0
  44. data/guides/assets/images/i18n/demo_untranslated.png +0 -0
  45. data/guides/assets/images/icons/README +5 -0
  46. data/guides/assets/images/icons/callouts/1.png +0 -0
  47. data/guides/assets/images/icons/callouts/10.png +0 -0
  48. data/guides/assets/images/icons/callouts/11.png +0 -0
  49. data/guides/assets/images/icons/callouts/12.png +0 -0
  50. data/guides/assets/images/icons/callouts/13.png +0 -0
  51. data/guides/assets/images/icons/callouts/14.png +0 -0
  52. data/guides/assets/images/icons/callouts/15.png +0 -0
  53. data/guides/assets/images/icons/callouts/2.png +0 -0
  54. data/guides/assets/images/icons/callouts/3.png +0 -0
  55. data/guides/assets/images/icons/callouts/4.png +0 -0
  56. data/guides/assets/images/icons/callouts/5.png +0 -0
  57. data/guides/assets/images/icons/callouts/6.png +0 -0
  58. data/guides/assets/images/icons/callouts/7.png +0 -0
  59. data/guides/assets/images/icons/callouts/8.png +0 -0
  60. data/guides/assets/images/icons/callouts/9.png +0 -0
  61. data/guides/assets/images/icons/caution.png +0 -0
  62. data/guides/assets/images/icons/example.png +0 -0
  63. data/guides/assets/images/icons/home.png +0 -0
  64. data/guides/assets/images/icons/important.png +0 -0
  65. data/guides/assets/images/icons/next.png +0 -0
  66. data/guides/assets/images/icons/note.png +0 -0
  67. data/guides/assets/images/icons/prev.png +0 -0
  68. data/guides/assets/images/icons/tip.png +0 -0
  69. data/guides/assets/images/icons/up.png +0 -0
  70. data/guides/assets/images/icons/warning.png +0 -0
  71. data/guides/assets/images/jaimeiniesta.jpg +0 -0
  72. data/guides/assets/images/nav_arrow.gif +0 -0
  73. data/guides/assets/images/oscardelben.jpg +0 -0
  74. data/guides/assets/images/polymorphic.png +0 -0
  75. data/guides/assets/images/radar.png +0 -0
  76. data/guides/assets/images/rails4_features.png +0 -0
  77. data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
  78. data/guides/assets/images/rails_guides_logo.gif +0 -0
  79. data/guides/assets/images/rails_logo_remix.gif +0 -0
  80. data/guides/assets/images/rails_welcome.png +0 -0
  81. data/guides/assets/images/session_fixation.png +0 -0
  82. data/guides/assets/images/tab_grey.gif +0 -0
  83. data/guides/assets/images/tab_info.gif +0 -0
  84. data/guides/assets/images/tab_note.gif +0 -0
  85. data/guides/assets/images/tab_red.gif +0 -0
  86. data/guides/assets/images/tab_yellow.gif +0 -0
  87. data/guides/assets/images/tab_yellow.png +0 -0
  88. data/guides/assets/images/vijaydev.jpg +0 -0
  89. data/guides/assets/javascripts/guides.js +57 -0
  90. data/guides/assets/javascripts/jquery.min.js +4 -0
  91. data/guides/assets/javascripts/responsive-tables.js +43 -0
  92. data/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js +59 -0
  93. data/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js +75 -0
  94. data/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js +59 -0
  95. data/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js +65 -0
  96. data/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js +100 -0
  97. data/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js +97 -0
  98. data/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js +91 -0
  99. data/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js +55 -0
  100. data/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js +41 -0
  101. data/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js +52 -0
  102. data/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js +67 -0
  103. data/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js +52 -0
  104. data/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js +57 -0
  105. data/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js +58 -0
  106. data/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js +72 -0
  107. data/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js +88 -0
  108. data/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js +33 -0
  109. data/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js +74 -0
  110. data/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js +64 -0
  111. data/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js +55 -0
  112. data/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js +94 -0
  113. data/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js +51 -0
  114. data/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js +66 -0
  115. data/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js +56 -0
  116. data/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js +69 -0
  117. data/guides/assets/javascripts/syntaxhighlighter/shCore.js +17 -0
  118. data/guides/assets/stylesheets/fixes.css +16 -0
  119. data/guides/assets/stylesheets/kindle.css +11 -0
  120. data/guides/assets/stylesheets/main.css +709 -0
  121. data/guides/assets/stylesheets/print.css +52 -0
  122. data/guides/assets/stylesheets/reset.css +43 -0
  123. data/guides/assets/stylesheets/responsive-tables.css +50 -0
  124. data/guides/assets/stylesheets/style.css +13 -0
  125. data/guides/assets/stylesheets/syntaxhighlighter/shCore.css +226 -0
  126. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css +328 -0
  127. data/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css +331 -0
  128. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css +339 -0
  129. data/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css +324 -0
  130. data/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +328 -0
  131. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css +324 -0
  132. data/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css +324 -0
  133. data/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css +324 -0
  134. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css +117 -0
  135. data/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css +120 -0
  136. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css +128 -0
  137. data/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css +113 -0
  138. data/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +117 -0
  139. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css +113 -0
  140. data/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css +113 -0
  141. data/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css +113 -0
  142. data/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +116 -0
  143. data/guides/code/getting_started/Gemfile +38 -0
  144. data/guides/code/getting_started/Gemfile.lock +150 -0
  145. data/guides/code/getting_started/README.rdoc +28 -0
  146. data/guides/code/getting_started/Rakefile +6 -0
  147. data/guides/code/getting_started/app/assets/images/rails.png +0 -0
  148. data/guides/code/getting_started/app/assets/javascripts/application.js +16 -0
  149. data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +3 -0
  150. data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +3 -0
  151. data/guides/code/getting_started/app/assets/javascripts/welcome.js.coffee +3 -0
  152. data/guides/code/getting_started/app/assets/stylesheets/application.css +13 -0
  153. data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +3 -0
  154. data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +3 -0
  155. data/guides/code/getting_started/app/assets/stylesheets/welcome.css.scss +3 -0
  156. data/guides/code/getting_started/app/controllers/application_controller.rb +5 -0
  157. data/guides/code/getting_started/app/controllers/comments_controller.rb +17 -0
  158. data/guides/code/getting_started/app/controllers/posts_controller.rb +47 -0
  159. data/guides/code/getting_started/app/controllers/welcome_controller.rb +4 -0
  160. data/guides/code/getting_started/app/helpers/application_helper.rb +2 -0
  161. data/guides/code/getting_started/app/helpers/comments_helper.rb +2 -0
  162. data/guides/code/getting_started/app/helpers/posts_helper.rb +2 -0
  163. data/guides/code/getting_started/app/helpers/welcome_helper.rb +2 -0
  164. data/guides/code/getting_started/app/models/comment.rb +3 -0
  165. data/guides/code/getting_started/app/models/post.rb +7 -0
  166. data/guides/code/getting_started/app/views/comments/_comment.html.erb +15 -0
  167. data/guides/code/getting_started/app/views/comments/_form.html.erb +13 -0
  168. data/guides/code/getting_started/app/views/layouts/application.html.erb +14 -0
  169. data/guides/code/getting_started/app/views/posts/_form.html.erb +27 -0
  170. data/guides/code/getting_started/app/views/posts/edit.html.erb +5 -0
  171. data/guides/code/getting_started/app/views/posts/index.html.erb +21 -0
  172. data/guides/code/getting_started/app/views/posts/new.html.erb +5 -0
  173. data/guides/code/getting_started/app/views/posts/show.html.erb +18 -0
  174. data/guides/code/getting_started/app/views/welcome/index.html.erb +3 -0
  175. data/guides/code/getting_started/bin/bundle +4 -0
  176. data/guides/code/getting_started/bin/rails +4 -0
  177. data/guides/code/getting_started/bin/rake +4 -0
  178. data/guides/code/getting_started/config.ru +4 -0
  179. data/guides/code/getting_started/config/application.rb +17 -0
  180. data/guides/code/getting_started/config/boot.rb +4 -0
  181. data/guides/code/getting_started/config/database.yml +25 -0
  182. data/guides/code/getting_started/config/environment.rb +5 -0
  183. data/guides/code/getting_started/config/environments/development.rb +30 -0
  184. data/guides/code/getting_started/config/environments/production.rb +80 -0
  185. data/guides/code/getting_started/config/environments/test.rb +36 -0
  186. data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +7 -0
  187. data/guides/code/getting_started/config/initializers/filter_parameter_logging.rb +4 -0
  188. data/guides/code/getting_started/config/initializers/inflections.rb +16 -0
  189. data/guides/code/getting_started/config/initializers/locale.rb +9 -0
  190. data/guides/code/getting_started/config/initializers/mime_types.rb +5 -0
  191. data/guides/code/getting_started/config/initializers/secret_token.rb +12 -0
  192. data/guides/code/getting_started/config/initializers/session_store.rb +3 -0
  193. data/guides/code/getting_started/config/initializers/wrap_parameters.rb +14 -0
  194. data/guides/code/getting_started/config/locales/en.yml +23 -0
  195. data/guides/code/getting_started/config/routes.rb +7 -0
  196. data/guides/code/getting_started/db/migrate/20130122042648_create_posts.rb +10 -0
  197. data/guides/code/getting_started/db/migrate/20130122045842_create_comments.rb +11 -0
  198. data/guides/code/getting_started/db/schema.rb +33 -0
  199. data/guides/code/getting_started/db/seeds.rb +7 -0
  200. data/guides/code/getting_started/public/404.html +27 -0
  201. data/guides/code/getting_started/public/422.html +26 -0
  202. data/guides/code/getting_started/public/500.html +26 -0
  203. data/guides/code/getting_started/public/favicon.ico +0 -0
  204. data/guides/code/getting_started/public/robots.txt +5 -0
  205. data/guides/code/getting_started/test/controllers/comments_controller_test.rb +7 -0
  206. data/guides/code/getting_started/test/controllers/posts_controller_test.rb +7 -0
  207. data/guides/code/getting_started/test/controllers/welcome_controller_test.rb +9 -0
  208. data/guides/code/getting_started/test/fixtures/comments.yml +11 -0
  209. data/guides/code/getting_started/test/fixtures/posts.yml +9 -0
  210. data/guides/code/getting_started/test/helpers/comments_helper_test.rb +4 -0
  211. data/guides/code/getting_started/test/helpers/posts_helper_test.rb +4 -0
  212. data/guides/code/getting_started/test/helpers/welcome_helper_test.rb +4 -0
  213. data/guides/code/getting_started/test/models/comment_test.rb +7 -0
  214. data/guides/code/getting_started/test/models/post_test.rb +7 -0
  215. data/guides/code/getting_started/test/test_helper.rb +15 -0
  216. data/guides/rails_guides.rb +44 -0
  217. data/guides/rails_guides/generator.rb +248 -0
  218. data/guides/rails_guides/helpers.rb +51 -0
  219. data/guides/rails_guides/indexer.rb +68 -0
  220. data/guides/rails_guides/kindle.rb +119 -0
  221. data/guides/rails_guides/levenshtein.rb +31 -0
  222. data/guides/rails_guides/markdown.rb +163 -0
  223. data/guides/rails_guides/markdown/renderer.rb +82 -0
  224. data/guides/source/2_2_release_notes.md +435 -0
  225. data/guides/source/2_3_release_notes.md +621 -0
  226. data/guides/source/3_0_release_notes.md +614 -0
  227. data/guides/source/3_1_release_notes.md +556 -0
  228. data/guides/source/3_2_release_notes.md +565 -0
  229. data/guides/source/4_0_release_notes.md +228 -0
  230. data/guides/source/_license.html.erb +2 -0
  231. data/guides/source/_welcome.html.erb +19 -0
  232. data/guides/source/action_controller_overview.md +872 -0
  233. data/guides/source/action_mailer_basics.md +599 -0
  234. data/guides/source/action_view_overview.md +1565 -0
  235. data/guides/source/active_model_basics.md +200 -0
  236. data/guides/source/active_record_basics.md +370 -0
  237. data/guides/source/active_record_callbacks.md +358 -0
  238. data/guides/source/active_record_querying.md +1621 -0
  239. data/guides/source/active_record_validations.md +1128 -0
  240. data/guides/source/active_support_core_extensions.md +3791 -0
  241. data/guides/source/active_support_instrumentation.md +487 -0
  242. data/guides/source/api_documentation_guidelines.md +209 -0
  243. data/guides/source/asset_pipeline.md +832 -0
  244. data/guides/source/association_basics.md +2129 -0
  245. data/guides/source/caching_with_rails.md +350 -0
  246. data/guides/source/command_line.md +594 -0
  247. data/guides/source/configuring.md +736 -0
  248. data/guides/source/contributing_to_ruby_on_rails.md +455 -0
  249. data/guides/source/credits.html.erb +76 -0
  250. data/guides/source/debugging_rails_applications.md +675 -0
  251. data/guides/source/development_dependencies_install.md +195 -0
  252. data/guides/source/documents.yaml +179 -0
  253. data/guides/source/engines.md +961 -0
  254. data/guides/source/form_helpers.md +955 -0
  255. data/guides/source/generators.md +644 -0
  256. data/guides/source/getting_started.md +1775 -0
  257. data/guides/source/i18n.md +983 -0
  258. data/guides/source/index.html.erb +27 -0
  259. data/guides/source/initialization.md +562 -0
  260. data/guides/source/kindle/KINDLE.md +26 -0
  261. data/guides/source/kindle/copyright.html.erb +1 -0
  262. data/guides/source/kindle/layout.html.erb +27 -0
  263. data/guides/source/kindle/rails_guides.opf.erb +52 -0
  264. data/guides/source/kindle/toc.html.erb +24 -0
  265. data/guides/source/kindle/toc.ncx.erb +64 -0
  266. data/guides/source/kindle/welcome.html.erb +5 -0
  267. data/guides/source/layout.html.erb +148 -0
  268. data/guides/source/layouts_and_rendering.md +1132 -0
  269. data/guides/source/migrations.md +1059 -0
  270. data/guides/source/nested_model_forms.md +225 -0
  271. data/guides/source/plugins.md +435 -0
  272. data/guides/source/rails_application_templates.md +229 -0
  273. data/guides/source/rails_on_rack.md +342 -0
  274. data/guides/source/routing.md +1088 -0
  275. data/guides/source/ruby_on_rails_guides_guidelines.md +124 -0
  276. data/guides/source/security.md +973 -0
  277. data/guides/source/testing.md +981 -0
  278. data/guides/source/upgrading_ruby_on_rails.md +286 -0
  279. data/guides/source/working_with_javascript_in_rails.md +396 -0
  280. data/guides/w3c_validator.rb +95 -0
  281. metadata +315 -31
@@ -0,0 +1,1059 @@
1
+ Active Record Migrations
2
+ ========================
3
+
4
+ Migrations are a feature of Active Record that allows you to evolve your
5
+ database schema over time. Rather than write schema modifications in pure SQL,
6
+ migrations allow you to use an easy Ruby DSL to describe changes to your
7
+ tables.
8
+
9
+ After reading this guide, you will know:
10
+
11
+ * The generators you can use to create them.
12
+ * The methods Active Record provides to manipulate your database.
13
+ * The Rake tasks that manipulate migrations and your schema.
14
+ * How migrations relate to `schema.rb`.
15
+
16
+ --------------------------------------------------------------------------------
17
+
18
+ Migration Overview
19
+ ------------------
20
+
21
+ Migrations are a convenient way to alter your database schema over time in a
22
+ consistent and easy way. They use a Ruby DSL so that you don't have to write
23
+ SQL by hand, allowing your schema and changes to be database independent.
24
+
25
+ You can think of each migration as being a new 'version' of the database. A
26
+ schema starts off with nothing in it, and each migration modifies it to add or
27
+ remove tables, columns, or entries. Active Record knows how to update your
28
+ schema along this timeline, bringing it from whatever point it is in the
29
+ history to the latest version. Active Record will also update your
30
+ `db/schema.rb` file to match the up-to-date structure of your database.
31
+
32
+ Here's an example of a migration:
33
+
34
+ ```ruby
35
+ class CreateProducts < ActiveRecord::Migration
36
+ def change
37
+ create_table :products do |t|
38
+ t.string :name
39
+ t.text :description
40
+
41
+ t.timestamps
42
+ end
43
+ end
44
+ end
45
+ ```
46
+
47
+ This migration adds a table called `products` with a string column called
48
+ `name` and a text column called `description`. A primary key column called `id`
49
+ will also be added implicitly, as it's the default primary key for all Active
50
+ Record models. The `timestamps` macro adds two columns, `created_at` and
51
+ `updated_at`. These special columns are automatically managed by Active Record
52
+ if they exist.
53
+
54
+ Note that we define the change that we want to happen moving forward in time.
55
+ Before this migration is run, there will be no table. After, the table will
56
+ exist. Active Record knows how to reverse this migration as well: if we roll
57
+ this migration back, it will remove the table.
58
+
59
+ On databases that support transactions with statements that change the schema,
60
+ migrations are wrapped in a transaction. If the database does not support this
61
+ then when a migration fails the parts of it that succeeded will not be rolled
62
+ back. You will have to rollback the changes that were made by hand.
63
+
64
+ If you wish for a migration to do something that Active Record doesn't know how
65
+ to reverse, you can use `reversible`:
66
+
67
+ ```ruby
68
+ class ChangeProductsPrice < ActiveRecord::Migration
69
+ def change
70
+ reversible do |dir|
71
+ change_table :products do |t|
72
+ dir.up { t.change :price, :string }
73
+ dir.down { t.change :price, :integer }
74
+ end
75
+ end
76
+ end
77
+ end
78
+ ```
79
+
80
+ Alternatively, you can use `up` and `down` instead of `change`:
81
+
82
+ ```ruby
83
+ class ChangeProductsPrice < ActiveRecord::Migration
84
+ def up
85
+ change_table :products do |t|
86
+ t.change :price, :string
87
+ end
88
+ end
89
+
90
+ def down
91
+ change_table :products do |t|
92
+ t.change :price, :integer
93
+ end
94
+ end
95
+ end
96
+ ```
97
+
98
+ Creating a Migration
99
+ --------------------
100
+
101
+ ### Creating a Standalone Migration
102
+
103
+ Migrations are stored as files in the `db/migrate` directory, one for each
104
+ migration class. The name of the file is of the form
105
+ `YYYYMMDDHHMMSS_create_products.rb`, that is to say a UTC timestamp
106
+ identifying the migration followed by an underscore followed by the name
107
+ of the migration. The name of the migration class (CamelCased version)
108
+ should match the latter part of the file name. For example
109
+ `20080906120000_create_products.rb` should define class `CreateProducts` and
110
+ `20080906120001_add_details_to_products.rb` should define
111
+ `AddDetailsToProducts`. Rails uses this timestamp to determine which migration
112
+ should be run and in what order, so if you're copying a migration from another
113
+ application or generate a file yourself, be aware of its position in the order.
114
+
115
+ Of course, calculating timestamps is no fun, so Active Record provides a
116
+ generator to handle making it for you:
117
+
118
+ ```bash
119
+ $ rails generate migration AddPartNumberToProducts
120
+ ```
121
+
122
+ This will create an empty but appropriately named migration:
123
+
124
+ ```ruby
125
+ class AddPartNumberToProducts < ActiveRecord::Migration
126
+ def change
127
+ end
128
+ end
129
+ ```
130
+
131
+ If the migration name is of the form "AddXXXToYYY" or "RemoveXXXFromYYY" and is
132
+ followed by a list of column names and types then a migration containing the
133
+ appropriate `add_column` and `remove_column` statements will be created.
134
+
135
+ ```bash
136
+ $ rails generate migration AddPartNumberToProducts part_number:string
137
+ ```
138
+
139
+ will generate
140
+
141
+ ```ruby
142
+ class AddPartNumberToProducts < ActiveRecord::Migration
143
+ def change
144
+ add_column :products, :part_number, :string
145
+ end
146
+ end
147
+ ```
148
+
149
+ Similarly,
150
+
151
+ ```bash
152
+ $ rails generate migration RemovePartNumberFromProducts part_number:string
153
+ ```
154
+
155
+ generates
156
+
157
+ ```ruby
158
+ class RemovePartNumberFromProducts < ActiveRecord::Migration
159
+ def change
160
+ remove_column :products, :part_number, :string
161
+ end
162
+ end
163
+ ```
164
+
165
+ You are not limited to one magically generated column. For example
166
+
167
+ ```bash
168
+ $ rails generate migration AddDetailsToProducts part_number:string price:decimal
169
+ ```
170
+
171
+ generates
172
+
173
+ ```ruby
174
+ class AddDetailsToProducts < ActiveRecord::Migration
175
+ def change
176
+ add_column :products, :part_number, :string
177
+ add_column :products, :price, :decimal
178
+ end
179
+ end
180
+ ```
181
+
182
+ As always, what has been generated for you is just a starting point. You can add
183
+ or remove from it as you see fit by editing the
184
+ `db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb` file.
185
+
186
+ Also, the generator accepts column type as `references`(also available as
187
+ `belongs_to`). For instance
188
+
189
+ ```bash
190
+ $ rails generate migration AddUserRefToProducts user:references
191
+ ```
192
+
193
+ generates
194
+
195
+ ```ruby
196
+ class AddUserRefToProducts < ActiveRecord::Migration
197
+ def change
198
+ add_reference :products, :user, index: true
199
+ end
200
+ end
201
+ ```
202
+
203
+ This migration will create a `user_id` column and appropriate index.
204
+
205
+ There is also a generator which will produce join tables if `JoinTable` is part of the name:
206
+
207
+ ```bash
208
+ rails g migration CreateJoinTableCustomerProduct customer product
209
+ ```
210
+
211
+ will produce the following migration:
212
+
213
+ ```ruby
214
+ class CreateJoinTableCustomerProduct < ActiveRecord::Migration
215
+ def change
216
+ create_join_table :customers, :products do |t|
217
+ # t.index [:customer_id, :product_id]
218
+ # t.index [:product_id, :customer_id]
219
+ end
220
+ end
221
+ end
222
+ ```
223
+
224
+ ### Model Generators
225
+
226
+ The model and scaffold generators will create migrations appropriate for adding
227
+ a new model. This migration will already contain instructions for creating the
228
+ relevant table. If you tell Rails what columns you want, then statements for
229
+ adding these columns will also be created. For example, running
230
+
231
+ ```bash
232
+ $ rails generate model Product name:string description:text
233
+ ```
234
+
235
+ will create a migration that looks like this
236
+
237
+ ```ruby
238
+ class CreateProducts < ActiveRecord::Migration
239
+ def change
240
+ create_table :products do |t|
241
+ t.string :name
242
+ t.text :description
243
+
244
+ t.timestamps
245
+ end
246
+ end
247
+ end
248
+ ```
249
+
250
+ You can append as many column name/type pairs as you want.
251
+
252
+ ### Supported Type Modifiers
253
+
254
+ You can also specify some options just after the field type between curly
255
+ braces. You can use the following modifiers:
256
+
257
+ * `limit` Sets the maximum size of the `string/text/binary/integer` fields
258
+ * `precision` Defines the precision for the `decimal` fields
259
+ * `scale` Defines the scale for the `decimal` fields
260
+ * `polymorphic` Adds a `type` column for `belongs_to` associations
261
+
262
+ For instance, running
263
+
264
+ ```bash
265
+ $ rails generate migration AddDetailsToProducts price:decimal{5,2} supplier:references{polymorphic}
266
+ ```
267
+
268
+ will produce a migration that looks like this
269
+
270
+ ```ruby
271
+ class AddDetailsToProducts < ActiveRecord::Migration
272
+ def change
273
+ add_column :products, :price, precision: 5, scale: 2
274
+ add_reference :products, :user, polymorphic: true, index: true
275
+ end
276
+ end
277
+ ```
278
+
279
+ Writing a Migration
280
+ -------------------
281
+
282
+ Once you have created your migration using one of the generators it's time to
283
+ get to work!
284
+
285
+ ### Creating a Table
286
+
287
+ The `create_table` method is one of the most fundamental, but most of the time,
288
+ will be generated for you from using a model or scaffold generator. A typical
289
+ use would be
290
+
291
+ ```ruby
292
+ create_table :products do |t|
293
+ t.string :name
294
+ end
295
+ ```
296
+
297
+ which creates a `products` table with a column called `name` (and as discussed
298
+ below, an implicit `id` column).
299
+
300
+ By default, `create_table` will create a primary key called `id`. You can change
301
+ the name of the primary key with the `:primary_key` option (don't forget to
302
+ update the corresponding model) or, if you don't want a primary key at all, you
303
+ can pass the option `id: false`. If you need to pass database specific options
304
+ you can place an SQL fragment in the `:options` option. For example,
305
+
306
+ ```ruby
307
+ create_table :products, options: "ENGINE=BLACKHOLE" do |t|
308
+ t.string :name, null: false
309
+ end
310
+ ```
311
+
312
+ will append `ENGINE=BLACKHOLE` to the SQL statement used to create the table
313
+ (when using MySQL, the default is `ENGINE=InnoDB`).
314
+
315
+ ### Creating a Join Table
316
+
317
+ Migration method `create_join_table` creates a HABTM join table. A typical use
318
+ would be
319
+
320
+ ```ruby
321
+ create_join_table :products, :categories
322
+ ```
323
+
324
+ which creates a `categories_products` table with two columns called
325
+ `category_id` and `product_id`. These columns have the option `:null` set to
326
+ `false` by default.
327
+
328
+ You can pass the option `:table_name` with you want to customize the table
329
+ name. For example,
330
+
331
+ ```ruby
332
+ create_join_table :products, :categories, table_name: :categorization
333
+ ```
334
+
335
+ will create a `categorization` table.
336
+
337
+ By default, `create_join_table` will create two columns with no options, but
338
+ you can specify these options using the `:column_options` option. For example,
339
+
340
+ ```ruby
341
+ create_join_table :products, :categories, column_options: {null: true}
342
+ ```
343
+
344
+ will create the `product_id` and `category_id` with the `:null` option as
345
+ `true`.
346
+
347
+ `create_join_table` also accepts a block, which you can use to add indices
348
+ (which are not created by default) or additional columns:
349
+
350
+ ```ruby
351
+ create_join_table :products, :categories do |t|
352
+ t.index :products
353
+ t.index :categories
354
+ end
355
+ ```
356
+
357
+ ### Changing Tables
358
+
359
+ A close cousin of `create_table` is `change_table`, used for changing existing
360
+ tables. It is used in a similar fashion to `create_table` but the object
361
+ yielded to the block knows more tricks. For example
362
+
363
+ ```ruby
364
+ change_table :products do |t|
365
+ t.remove :description, :name
366
+ t.string :part_number
367
+ t.index :part_number
368
+ t.rename :upccode, :upc_code
369
+ end
370
+ ```
371
+
372
+ removes the `description` and `name` columns, creates a `part_number` string
373
+ column and adds an index on it. Finally it renames the `upccode` column.
374
+
375
+ ### When Helpers aren't Enough
376
+
377
+ If the helpers provided by Active Record aren't enough you can use the `execute`
378
+ method to execute arbitrary SQL:
379
+
380
+ ```ruby
381
+ Products.connection.execute('UPDATE `products` SET `price`=`free` WHERE 1')
382
+ ```
383
+
384
+ For more details and examples of individual methods, check the API documentation.
385
+ In particular the documentation for
386
+ [`ActiveRecord::ConnectionAdapters::SchemaStatements`](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html)
387
+ (which provides the methods available in the `change`, `up` and `down` methods),
388
+ [`ActiveRecord::ConnectionAdapters::TableDefinition`](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html)
389
+ (which provides the methods available on the object yielded by `create_table`)
390
+ and
391
+ [`ActiveRecord::ConnectionAdapters::Table`](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html)
392
+ (which provides the methods available on the object yielded by `change_table`).
393
+
394
+ ### Using the `change` Method
395
+
396
+ The `change` method is the primary way of writing migrations. It works for the
397
+ majority of cases, where Active Record knows how to reverse the migration
398
+ automatically. Currently, the `change` method supports only these migration
399
+ definitions:
400
+
401
+ * `add_column`
402
+ * `add_index`
403
+ * `add_reference`
404
+ * `add_timestamps`
405
+ * `create_table`
406
+ * `create_join_table`
407
+ * `drop_table` (must supply a block)
408
+ * `drop_join_table` (must supply a block)
409
+ * `remove_timestamps`
410
+ * `rename_column`
411
+ * `rename_index`
412
+ * `remove_reference`
413
+ * `rename_table`
414
+
415
+ `change_table` is also reversible, as long as the block does not call `change`,
416
+ `change_default` or `remove`.
417
+
418
+ If you're going to need to use any other methods, you should use `reversible`
419
+ or write the `up` and `down` methods instead of using the `change` method.
420
+
421
+ ### Using `reversible`
422
+
423
+ Complex migrations may require processing that Active Record doesn't know how
424
+ to reverse. You can use `reversible` to specify what to do when running a
425
+ migration what else to do when reverting it. For example,
426
+
427
+ ```ruby
428
+ class ExampleMigration < ActiveRecord::Migration
429
+ def change
430
+ create_table :products do |t|
431
+ t.references :category
432
+ end
433
+
434
+ reversible do |dir|
435
+ dir.up do
436
+ #add a foreign key
437
+ execute <<-SQL
438
+ ALTER TABLE products
439
+ ADD CONSTRAINT fk_products_categories
440
+ FOREIGN KEY (category_id)
441
+ REFERENCES categories(id)
442
+ SQL
443
+ end
444
+ dir.down do
445
+ execute <<-SQL
446
+ ALTER TABLE products
447
+ DROP FOREIGN KEY fk_products_categories
448
+ SQL
449
+ end
450
+ end
451
+
452
+ add_column :users, :home_page_url, :string
453
+ rename_column :users, :email, :email_address
454
+ end
455
+ ```
456
+
457
+ Using `reversible` will ensure that the instructions are executed in the
458
+ right order too. If the previous example migration is reverted,
459
+ the `down` block will be run after the `home_page_url` column is removed and
460
+ right before the table `products` is dropped.
461
+
462
+ Sometimes your migration will do something which is just plain irreversible; for
463
+ example, it might destroy some data. In such cases, you can raise
464
+ `ActiveRecord::IrreversibleMigration` in your `down` block. If someone tries
465
+ to revert your migration, an error message will be displayed saying that it
466
+ can't be done.
467
+
468
+ ### Using the `up`/`down` Methods
469
+
470
+ You can also use the old style of migration using `up` and `down` methods
471
+ instead of the `change` method.
472
+ The `up` method should describe the transformation you'd like to make to your
473
+ schema, and the `down` method of your migration should revert the
474
+ transformations done by the `up` method. In other words, the database schema
475
+ should be unchanged if you do an `up` followed by a `down`. For example, if you
476
+ create a table in the `up` method, you should drop it in the `down` method. It
477
+ is wise to reverse the transformations in precisely the reverse order they were
478
+ made in the `up` method. The example in the `reversible` section is equivalent to:
479
+
480
+ ```ruby
481
+ class ExampleMigration < ActiveRecord::Migration
482
+ def up
483
+ create_table :products do |t|
484
+ t.references :category
485
+ end
486
+
487
+ # add a foreign key
488
+ execute <<-SQL
489
+ ALTER TABLE products
490
+ ADD CONSTRAINT fk_products_categories
491
+ FOREIGN KEY (category_id)
492
+ REFERENCES categories(id)
493
+ SQL
494
+
495
+ add_column :users, :home_page_url, :string
496
+ rename_column :users, :email, :email_address
497
+ end
498
+
499
+ def down
500
+ rename_column :users, :email_address, :email
501
+ remove_column :users, :home_page_url
502
+
503
+ execute <<-SQL
504
+ ALTER TABLE products
505
+ DROP FOREIGN KEY fk_products_categories
506
+ SQL
507
+
508
+ drop_table :products
509
+ end
510
+ end
511
+ ```
512
+
513
+ If your migration is irreversible, you should raise
514
+ `ActiveRecord::IrreversibleMigration` from your `down` method. If someone tries
515
+ to revert your migration, an error message will be displayed saying that it
516
+ can't be done.
517
+
518
+ ### Reverting Previous Migrations
519
+
520
+ You can use Active Record's ability to rollback migrations using the `revert` method:
521
+
522
+ ```ruby
523
+ require_relative '2012121212_example_migration'
524
+
525
+ class FixupExampleMigration < ActiveRecord::Migration
526
+ def change
527
+ revert ExampleMigration
528
+
529
+ create_table(:apples) do |t|
530
+ t.string :variety
531
+ end
532
+ end
533
+ end
534
+ ```
535
+
536
+ The `revert` method also accepts a block of instructions to reverse.
537
+ This could be useful to revert selected parts of previous migrations.
538
+ For example, let's imagine that `ExampleMigration` is committed and it
539
+ is later decided it would be best to serialize the product list instead.
540
+ One could write:
541
+
542
+ ```ruby
543
+ class SerializeProductListMigration < ActiveRecord::Migration
544
+ def change
545
+ add_column :categories, :product_list
546
+
547
+ reversible do |dir|
548
+ dir.up do
549
+ # transfer data from Products to Category#product_list
550
+ end
551
+ dir.down do
552
+ # create Products from Category#product_list
553
+ end
554
+ end
555
+
556
+ revert do
557
+ # copy-pasted code from ExampleMigration
558
+ create_table :products do |t|
559
+ t.references :category
560
+ end
561
+
562
+ reversible do |dir|
563
+ dir.up do
564
+ #add a foreign key
565
+ execute <<-SQL
566
+ ALTER TABLE products
567
+ ADD CONSTRAINT fk_products_categories
568
+ FOREIGN KEY (category_id)
569
+ REFERENCES categories(id)
570
+ SQL
571
+ end
572
+ dir.down do
573
+ execute <<-SQL
574
+ ALTER TABLE products
575
+ DROP FOREIGN KEY fk_products_categories
576
+ SQL
577
+ end
578
+ end
579
+
580
+ # The rest of the migration was ok
581
+ end
582
+ end
583
+ end
584
+ ```
585
+
586
+ The same migration could also have been written without using `revert`
587
+ but this would have involved a few more steps: reversing the order
588
+ of `create_table` and `reversible`, replacing `create_table`
589
+ by `drop_table`, and finally replacing `up` by `down` and vice-versa.
590
+ This is all taken care of by `revert`.
591
+
592
+ Running Migrations
593
+ ------------------
594
+
595
+ Rails provides a set of Rake tasks to run certain sets of migrations.
596
+
597
+ The very first migration related Rake task you will use will probably be
598
+ `rake db:migrate`. In its most basic form it just runs the `change` or `up`
599
+ method for all the migrations that have not yet been run. If there are
600
+ no such migrations, it exits. It will run these migrations in order based
601
+ on the date of the migration.
602
+
603
+ Note that running the `db:migrate` also invokes the `db:schema:dump` task, which
604
+ will update your `db/schema.rb` file to match the structure of your database.
605
+
606
+ If you specify a target version, Active Record will run the required migrations
607
+ (change, up, down) until it has reached the specified version. The version
608
+ is the numerical prefix on the migration's filename. For example, to migrate
609
+ to version 20080906120000 run
610
+
611
+ ```bash
612
+ $ rake db:migrate VERSION=20080906120000
613
+ ```
614
+
615
+ If version 20080906120000 is greater than the current version (i.e., it is
616
+ migrating upwards), this will run the `change` (or `up`) method
617
+ on all migrations up to and
618
+ including 20080906120000, and will not execute any later migrations. If
619
+ migrating downwards, this will run the `down` method on all the migrations
620
+ down to, but not including, 20080906120000.
621
+
622
+ ### Rolling Back
623
+
624
+ A common task is to rollback the last migration. For example, if you made a
625
+ mistake in it and wish to correct it. Rather than tracking down the version
626
+ number associated with the previous migration you can run
627
+
628
+ ```bash
629
+ $ rake db:rollback
630
+ ```
631
+
632
+ This will rollback the latest migration, either by reverting the `change`
633
+ method or by running the `down` method. If you need to undo
634
+ several migrations you can provide a `STEP` parameter:
635
+
636
+ ```bash
637
+ $ rake db:rollback STEP=3
638
+ ```
639
+
640
+ will revert the last 3 migrations.
641
+
642
+ The `db:migrate:redo` task is a shortcut for doing a rollback and then migrating
643
+ back up again. As with the `db:rollback` task, you can use the `STEP` parameter
644
+ if you need to go more than one version back, for example
645
+
646
+ ```bash
647
+ $ rake db:migrate:redo STEP=3
648
+ ```
649
+
650
+ Neither of these Rake tasks do anything you could not do with `db:migrate`. They
651
+ are simply more convenient, since you do not need to explicitly specify the
652
+ version to migrate to.
653
+
654
+ ### Resetting the Database
655
+
656
+ The `rake db:reset` task will drop the database, recreate it and load the
657
+ current schema into it.
658
+
659
+ NOTE: This is not the same as running all the migrations. It will only use the
660
+ contents of the current schema.rb file. If a migration can't be rolled back,
661
+ 'rake db:reset' may not help you. To find out more about dumping the schema see
662
+ '[schema dumping and you](#schema-dumping-and-you).'
663
+
664
+ ### Running Specific Migrations
665
+
666
+ If you need to run a specific migration up or down, the `db:migrate:up` and
667
+ `db:migrate:down` tasks will do that. Just specify the appropriate version and
668
+ the corresponding migration will have its `change`, `up` or `down` method
669
+ invoked, for example,
670
+
671
+ ```bash
672
+ $ rake db:migrate:up VERSION=20080906120000
673
+ ```
674
+
675
+ will run the 20080906120000 migration by running the `change` method (or the
676
+ `up` method). This task will
677
+ first check whether the migration is already performed and will do nothing if
678
+ Active Record believes that it has already been run.
679
+
680
+ ### Running Migrations in Different Environments
681
+
682
+ By default running `rake db:migrate` will run in the `development` environment.
683
+ To run migrations against another environment you can specify it using the
684
+ `RAILS_ENV` environment variable while running the command. For example to run
685
+ migrations against the `test` environment you could run:
686
+
687
+ ```bash
688
+ $ rake db:migrate RAILS_ENV=test
689
+ ```
690
+
691
+ ### Changing the Output of Running Migrations
692
+
693
+ By default migrations tell you exactly what they're doing and how long it took.
694
+ A migration creating a table and adding an index might produce output like this
695
+
696
+ ```bash
697
+ == CreateProducts: migrating =================================================
698
+ -- create_table(:products)
699
+ -> 0.0028s
700
+ == CreateProducts: migrated (0.0028s) ========================================
701
+ ```
702
+
703
+ Several methods are provided in migrations that allow you to control all this:
704
+
705
+ | Method | Purpose
706
+ | -------------------- | -------
707
+ | suppress_messages | Takes a block as an argument and suppresses any output generated by the block.
708
+ | say | Takes a message argument and outputs it as is. A second boolean argument can be passed to specify whether to indent or not.
709
+ | 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.
710
+
711
+ For example, this migration
712
+
713
+ ```ruby
714
+ class CreateProducts < ActiveRecord::Migration
715
+ def change
716
+ suppress_messages do
717
+ create_table :products do |t|
718
+ t.string :name
719
+ t.text :description
720
+ t.timestamps
721
+ end
722
+ end
723
+
724
+ say "Created a table"
725
+
726
+ suppress_messages {add_index :products, :name}
727
+ say "and an index!", true
728
+
729
+ say_with_time 'Waiting for a while' do
730
+ sleep 10
731
+ 250
732
+ end
733
+ end
734
+ end
735
+ ```
736
+
737
+ generates the following output
738
+
739
+ ```bash
740
+ == CreateProducts: migrating =================================================
741
+ -- Created a table
742
+ -> and an index!
743
+ -- Waiting for a while
744
+ -> 10.0013s
745
+ -> 250 rows
746
+ == CreateProducts: migrated (10.0054s) =======================================
747
+ ```
748
+
749
+ If you want Active Record to not output anything, then running `rake db:migrate
750
+ VERBOSE=false` will suppress all output.
751
+
752
+ Changing Existing Migrations
753
+ ----------------------------
754
+
755
+ Occasionally you will make a mistake when writing a migration. If you have
756
+ already run the migration then you cannot just edit the migration and run the
757
+ migration again: Rails thinks it has already run the migration and so will do
758
+ nothing when you run `rake db:migrate`. You must rollback the migration (for
759
+ example with `rake db:rollback`), edit your migration and then run
760
+ `rake db:migrate` to run the corrected version.
761
+
762
+ In general, editing existing migrations is not a good idea. You will be
763
+ creating extra work for yourself and your co-workers and cause major headaches
764
+ if the existing version of the migration has already been run on production
765
+ machines. Instead, you should write a new migration that performs the changes
766
+ you require. Editing a freshly generated migration that has not yet been
767
+ committed to source control (or, more generally, which has not been propagated
768
+ beyond your development machine) is relatively harmless.
769
+
770
+ The `revert` method can be helpful when writing a new migration to undo
771
+ previous migrations in whole or in part
772
+ (see [Reverting Previous Migrations](#reverting-previous-migrations) above).
773
+
774
+ Using Models in Your Migrations
775
+ -------------------------------
776
+
777
+ When creating or updating data in a migration it is often tempting to use one
778
+ of your models. After all, they exist to provide easy access to the underlying
779
+ data. This can be done, but some caution should be observed.
780
+
781
+ For example, problems occur when the model uses database columns which are (1)
782
+ not currently in the database and (2) will be created by this or a subsequent
783
+ migration.
784
+
785
+ Consider this example, where Alice and Bob are working on the same code base
786
+ which contains a `Product` model:
787
+
788
+ Bob goes on vacation.
789
+
790
+ Alice creates a migration for the `products` table which adds a new column and
791
+ initializes it. She also adds a validation to the `Product` model for the new
792
+ column.
793
+
794
+ ```ruby
795
+ # db/migrate/20100513121110_add_flag_to_product.rb
796
+
797
+ class AddFlagToProduct < ActiveRecord::Migration
798
+ def change
799
+ add_column :products, :flag, :boolean
800
+ reversible do |dir|
801
+ dir.up { Product.update_all flag: false }
802
+ end
803
+ Product.update_all flag: false
804
+ end
805
+ end
806
+ ```
807
+
808
+ ```ruby
809
+ # app/model/product.rb
810
+
811
+ class Product < ActiveRecord::Base
812
+ validates :flag, presence: true
813
+ end
814
+ ```
815
+
816
+ Alice adds a second migration which adds and initializes another column to the
817
+ `products` table and also adds a validation to the `Product` model for the new
818
+ column.
819
+
820
+ ```ruby
821
+ # db/migrate/20100515121110_add_fuzz_to_product.rb
822
+
823
+ class AddFuzzToProduct < ActiveRecord::Migration
824
+ def change
825
+ add_column :products, :fuzz, :string
826
+ reversible do |dir|
827
+ dir.up { Product.update_all fuzz: 'fuzzy' }
828
+ end
829
+ end
830
+ end
831
+ ```
832
+
833
+ ```ruby
834
+ # app/model/product.rb
835
+
836
+ class Product < ActiveRecord::Base
837
+ validates :flag, :fuzz, presence: true
838
+ end
839
+ ```
840
+
841
+ Both migrations work for Alice.
842
+
843
+ Bob comes back from vacation and:
844
+
845
+ * Updates the source - which contains both migrations and the latest version
846
+ of the Product model.
847
+ * Runs outstanding migrations with `rake db:migrate`, which
848
+ includes the one that updates the `Product` model.
849
+
850
+ The migration crashes because when the model attempts to save, it tries to
851
+ validate the second added column, which is not in the database when the _first_
852
+ migration runs:
853
+
854
+ ```
855
+ rake aborted!
856
+ An error has occurred, this and all later migrations canceled:
857
+
858
+ undefined method `fuzz' for #<Product:0x000001049b14a0>
859
+ ```
860
+
861
+ A fix for this is to create a local model within the migration. This keeps
862
+ Rails from running the validations, so that the migrations run to completion.
863
+
864
+ When using a local model, it's a good idea to call
865
+ `Product.reset_column_information` to refresh the `ActiveRecord` cache for the
866
+ `Product` model prior to updating data in the database.
867
+
868
+ If Alice had done this instead, there would have been no problem:
869
+
870
+ ```ruby
871
+ # db/migrate/20100513121110_add_flag_to_product.rb
872
+
873
+ class AddFlagToProduct < ActiveRecord::Migration
874
+ class Product < ActiveRecord::Base
875
+ end
876
+
877
+ def change
878
+ add_column :products, :flag, :boolean
879
+ Product.reset_column_information
880
+ reversible do |dir|
881
+ dir.up { Product.update_all flag: false }
882
+ end
883
+ end
884
+ end
885
+ ```
886
+
887
+ ```ruby
888
+ # db/migrate/20100515121110_add_fuzz_to_product.rb
889
+
890
+ class AddFuzzToProduct < ActiveRecord::Migration
891
+ class Product < ActiveRecord::Base
892
+ end
893
+
894
+ def change
895
+ add_column :products, :fuzz, :string
896
+ Product.reset_column_information
897
+ reversible do |dir|
898
+ dir.up { Product.update_all fuzz: 'fuzzy' }
899
+ end
900
+ end
901
+ end
902
+ ```
903
+
904
+ There are other ways in which the above example could have gone badly.
905
+
906
+ For example, imagine that Alice creates a migration that selectively
907
+ updates the `description` field on certain products. She runs the
908
+ migration, commits the code, and then begins working on the next feature,
909
+ which is to add a new column `fuzz` to the products table.
910
+
911
+ She creates two migrations for this new feature, one which adds the new
912
+ column, and a second which selectively updates the `fuzz` column based on
913
+ other product attributes.
914
+
915
+ These migrations run just fine, but when Bob comes back from his vacation
916
+ and calls `rake db:migrate` to run all the outstanding migrations, he gets a
917
+ subtle bug: The descriptions have defaults, and the `fuzz` column is present,
918
+ but `fuzz` is nil on all products.
919
+
920
+ The solution is again to use `Product.reset_column_information` before
921
+ referencing the Product model in a migration, ensuring the Active Record's
922
+ knowledge of the table structure is current before manipulating data in those
923
+ records.
924
+
925
+ Schema Dumping and You
926
+ ----------------------
927
+
928
+ ### What are Schema Files for?
929
+
930
+ Migrations, mighty as they may be, are not the authoritative source for your
931
+ database schema. That role falls to either `db/schema.rb` or an SQL file which
932
+ Active Record generates by examining the database. They are not designed to be
933
+ edited, they just represent the current state of the database.
934
+
935
+ There is no need (and it is error prone) to deploy a new instance of an app by
936
+ replaying the entire migration history. It is much simpler and faster to just
937
+ load into the database a description of the current schema.
938
+
939
+ For example, this is how the test database is created: the current development
940
+ database is dumped (either to `db/schema.rb` or `db/structure.sql`) and then
941
+ loaded into the test database.
942
+
943
+ Schema files are also useful if you want a quick look at what attributes an
944
+ Active Record object has. This information is not in the model's code and is
945
+ frequently spread across several migrations, but the information is nicely
946
+ summed up in the schema file. The
947
+ [annotate_models](https://github.com/ctran/annotate_models) gem automatically
948
+ adds and updates comments at the top of each model summarizing the schema if
949
+ you desire that functionality.
950
+
951
+ ### Types of Schema Dumps
952
+
953
+ There are two ways to dump the schema. This is set in `config/application.rb`
954
+ by the `config.active_record.schema_format` setting, which may be either `:sql`
955
+ or `:ruby`.
956
+
957
+ If `:ruby` is selected then the schema is stored in `db/schema.rb`. If you look
958
+ at this file you'll find that it looks an awful lot like one very big
959
+ migration:
960
+
961
+ ```ruby
962
+ ActiveRecord::Schema.define(version: 20080906171750) do
963
+ create_table "authors", force: true do |t|
964
+ t.string "name"
965
+ t.datetime "created_at"
966
+ t.datetime "updated_at"
967
+ end
968
+
969
+ create_table "products", force: true do |t|
970
+ t.string "name"
971
+ t.text "description"
972
+ t.datetime "created_at"
973
+ t.datetime "updated_at"
974
+ t.string "part_number"
975
+ end
976
+ end
977
+ ```
978
+
979
+ In many ways this is exactly what it is. This file is created by inspecting the
980
+ database and expressing its structure using `create_table`, `add_index`, and so
981
+ on. Because this is database-independent, it could be loaded into any database
982
+ that Active Record supports. This could be very useful if you were to
983
+ distribute an application that is able to run against multiple databases.
984
+
985
+ There is however a trade-off: `db/schema.rb` cannot express database specific
986
+ items such as foreign key constraints, triggers, or stored procedures. While in
987
+ a migration you can execute custom SQL statements, the schema dumper cannot
988
+ reconstitute those statements from the database. If you are using features like
989
+ this, then you should set the schema format to `:sql`.
990
+
991
+ Instead of using Active Record's schema dumper, the database's structure will
992
+ be dumped using a tool specific to the database (via the `db:structure:dump`
993
+ Rake task) into `db/structure.sql`. For example, for PostgreSQL, the `pg_dump`
994
+ utility is used. For MySQL, this file will contain the output of `SHOW CREATE
995
+ TABLE` for the various tables.
996
+
997
+ Loading these schemas is simply a question of executing the SQL statements they
998
+ contain. By definition, this will create a perfect copy of the database's
999
+ structure. Using the `:sql` schema format will, however, prevent loading the
1000
+ schema into a RDBMS other than the one used to create it.
1001
+
1002
+ ### Schema Dumps and Source Control
1003
+
1004
+ Because schema dumps are the authoritative source for your database schema, it
1005
+ is strongly recommended that you check them into source control.
1006
+
1007
+ Active Record and Referential Integrity
1008
+ ---------------------------------------
1009
+
1010
+ The Active Record way claims that intelligence belongs in your models, not in
1011
+ the database. As such, features such as triggers or foreign key constraints,
1012
+ which push some of that intelligence back into the database, are not heavily
1013
+ used.
1014
+
1015
+ Validations such as `validates :foreign_key, uniqueness: true` are one way in
1016
+ which models can enforce data integrity. The `:dependent` option on
1017
+ associations allows models to automatically destroy child objects when the
1018
+ parent is destroyed. Like anything which operates at the application level,
1019
+ these cannot guarantee referential integrity and so some people augment them
1020
+ with foreign key constraints in the database.
1021
+
1022
+ Although Active Record does not provide any tools for working directly with
1023
+ such features, the `execute` method can be used to execute arbitrary SQL. You
1024
+ could also use some gem like
1025
+ [foreigner](https://github.com/matthuhiggins/foreigner) which add foreign key
1026
+ support to Active Record (including support for dumping foreign keys in
1027
+ `db/schema.rb`).
1028
+
1029
+ Migrations and Seed Data
1030
+ ------------------------
1031
+
1032
+ Some people use migrations to add data to the database:
1033
+
1034
+ ```ruby
1035
+ class AddInitialProducts < ActiveRecord::Migration
1036
+ def up
1037
+ 5.times do |i|
1038
+ Product.create(name: "Product ##{i}", description: "A product.")
1039
+ end
1040
+ end
1041
+
1042
+ def down
1043
+ Product.delete_all
1044
+ end
1045
+ end
1046
+ ```
1047
+
1048
+ However, Rails has a 'seeds' feature that should be used for seeding a database
1049
+ with initial data. It's a really simple feature: just fill up `db/seeds.rb`
1050
+ with some Ruby code, and run `rake db:seed`:
1051
+
1052
+ ```ruby
1053
+ 5.times do |i|
1054
+ Product.create(name: "Product ##{i}", description: "A product.")
1055
+ end
1056
+ ```
1057
+
1058
+ This is generally a much cleaner way to set up the database of a blank
1059
+ application.