openskies 0.0.5.2 → 0.0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +0 -87
- data/bin/openskies +31 -5
- metadata +4 -593
- data/guides/assets/images/belongs_to.png +0 -0
- data/guides/assets/images/book_icon.gif +0 -0
- data/guides/assets/images/bullet.gif +0 -0
- data/guides/assets/images/challenge.png +0 -0
- data/guides/assets/images/chapters_icon.gif +0 -0
- data/guides/assets/images/check_bullet.gif +0 -0
- data/guides/assets/images/credits_pic_blank.gif +0 -0
- data/guides/assets/images/csrf.png +0 -0
- data/guides/assets/images/customized_error_messages.png +0 -0
- data/guides/assets/images/edge_badge.png +0 -0
- data/guides/assets/images/error_messages.png +0 -0
- data/guides/assets/images/feature_tile.gif +0 -0
- data/guides/assets/images/footer_tile.gif +0 -0
- data/guides/assets/images/fxn.png +0 -0
- data/guides/assets/images/grey_bullet.gif +0 -0
- data/guides/assets/images/habtm.png +0 -0
- data/guides/assets/images/has_many.png +0 -0
- data/guides/assets/images/has_many_through.png +0 -0
- data/guides/assets/images/has_one.png +0 -0
- data/guides/assets/images/has_one_through.png +0 -0
- data/guides/assets/images/header_backdrop.png +0 -0
- data/guides/assets/images/header_tile.gif +0 -0
- data/guides/assets/images/i18n/demo_html_safe.png +0 -0
- data/guides/assets/images/i18n/demo_localized_pirate.png +0 -0
- data/guides/assets/images/i18n/demo_translated_en.png +0 -0
- data/guides/assets/images/i18n/demo_translated_pirate.png +0 -0
- data/guides/assets/images/i18n/demo_translation_missing.png +0 -0
- data/guides/assets/images/i18n/demo_untranslated.png +0 -0
- data/guides/assets/images/icons/README +0 -5
- data/guides/assets/images/icons/callouts/1.png +0 -0
- data/guides/assets/images/icons/callouts/10.png +0 -0
- data/guides/assets/images/icons/callouts/11.png +0 -0
- data/guides/assets/images/icons/callouts/12.png +0 -0
- data/guides/assets/images/icons/callouts/13.png +0 -0
- data/guides/assets/images/icons/callouts/14.png +0 -0
- data/guides/assets/images/icons/callouts/15.png +0 -0
- data/guides/assets/images/icons/callouts/2.png +0 -0
- data/guides/assets/images/icons/callouts/3.png +0 -0
- data/guides/assets/images/icons/callouts/4.png +0 -0
- data/guides/assets/images/icons/callouts/5.png +0 -0
- data/guides/assets/images/icons/callouts/6.png +0 -0
- data/guides/assets/images/icons/callouts/7.png +0 -0
- data/guides/assets/images/icons/callouts/8.png +0 -0
- data/guides/assets/images/icons/callouts/9.png +0 -0
- data/guides/assets/images/icons/caution.png +0 -0
- data/guides/assets/images/icons/example.png +0 -0
- data/guides/assets/images/icons/home.png +0 -0
- data/guides/assets/images/icons/important.png +0 -0
- data/guides/assets/images/icons/next.png +0 -0
- data/guides/assets/images/icons/note.png +0 -0
- data/guides/assets/images/icons/prev.png +0 -0
- data/guides/assets/images/icons/tip.png +0 -0
- data/guides/assets/images/icons/up.png +0 -0
- data/guides/assets/images/icons/warning.png +0 -0
- data/guides/assets/images/jaimeiniesta.jpg +0 -0
- data/guides/assets/images/nav_arrow.gif +0 -0
- data/guides/assets/images/polymorphic.png +0 -0
- data/guides/assets/images/posts_index.png +0 -0
- data/guides/assets/images/radar.png +0 -0
- data/guides/assets/images/rails_guides_kindle_cover.jpg +0 -0
- data/guides/assets/images/rails_guides_logo.gif +0 -0
- data/guides/assets/images/rails_logo_remix.gif +0 -0
- data/guides/assets/images/rails_welcome.png +0 -0
- data/guides/assets/images/session_fixation.png +0 -0
- data/guides/assets/images/tab_grey.gif +0 -0
- data/guides/assets/images/tab_info.gif +0 -0
- data/guides/assets/images/tab_note.gif +0 -0
- data/guides/assets/images/tab_red.gif +0 -0
- data/guides/assets/images/tab_yellow.gif +0 -0
- data/guides/assets/images/tab_yellow.png +0 -0
- data/guides/assets/images/validation_error_messages.png +0 -0
- data/guides/assets/images/vijaydev.jpg +0 -0
- data/guides/assets/javascripts/guides.js +0 -7
- data/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js +0 -59
- data/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js +0 -75
- data/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js +0 -59
- data/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js +0 -65
- data/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js +0 -100
- data/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js +0 -97
- data/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js +0 -91
- data/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js +0 -55
- data/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js +0 -41
- data/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js +0 -52
- data/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js +0 -67
- data/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js +0 -52
- data/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js +0 -57
- data/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js +0 -58
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js +0 -72
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js +0 -88
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js +0 -33
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js +0 -74
- data/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js +0 -64
- data/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js +0 -55
- data/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js +0 -94
- data/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js +0 -51
- data/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js +0 -66
- data/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js +0 -56
- data/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js +0 -69
- data/guides/assets/javascripts/syntaxhighlighter/shCore.js +0 -17
- data/guides/assets/stylesheets/fixes.css +0 -16
- data/guides/assets/stylesheets/kindle.css +0 -11
- data/guides/assets/stylesheets/main.css +0 -453
- data/guides/assets/stylesheets/print.css +0 -52
- data/guides/assets/stylesheets/reset.css +0 -43
- data/guides/assets/stylesheets/style.css +0 -13
- data/guides/assets/stylesheets/syntaxhighlighter/shCore.css +0 -226
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css +0 -328
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css +0 -331
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css +0 -339
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css +0 -324
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css +0 -328
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css +0 -324
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css +0 -324
- data/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css +0 -324
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css +0 -117
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css +0 -120
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css +0 -128
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css +0 -113
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css +0 -117
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css +0 -113
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css +0 -113
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css +0 -113
- data/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css +0 -116
- data/guides/code/getting_started/Gemfile +0 -38
- data/guides/code/getting_started/README.rdoc +0 -261
- data/guides/code/getting_started/Rakefile +0 -7
- data/guides/code/getting_started/app/assets/images/rails.png +0 -0
- data/guides/code/getting_started/app/assets/javascripts/application.js +0 -15
- data/guides/code/getting_started/app/assets/javascripts/comments.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/home.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/javascripts/posts.js.coffee +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/application.css +0 -13
- data/guides/code/getting_started/app/assets/stylesheets/comments.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/home.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/posts.css.scss +0 -3
- data/guides/code/getting_started/app/assets/stylesheets/scaffolds.css.scss +0 -56
- data/guides/code/getting_started/app/controllers/application_controller.rb +0 -3
- data/guides/code/getting_started/app/controllers/comments_controller.rb +0 -16
- data/guides/code/getting_started/app/controllers/home_controller.rb +0 -5
- data/guides/code/getting_started/app/controllers/posts_controller.rb +0 -84
- data/guides/code/getting_started/app/helpers/application_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/comments_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/home_helper.rb +0 -2
- data/guides/code/getting_started/app/helpers/posts_helper.rb +0 -5
- data/guides/code/getting_started/app/models/comment.rb +0 -3
- data/guides/code/getting_started/app/models/post.rb +0 -11
- data/guides/code/getting_started/app/models/tag.rb +0 -3
- data/guides/code/getting_started/app/views/comments/_comment.html.erb +0 -15
- data/guides/code/getting_started/app/views/comments/_form.html.erb +0 -13
- data/guides/code/getting_started/app/views/home/index.html.erb +0 -2
- data/guides/code/getting_started/app/views/layouts/application.html.erb +0 -14
- data/guides/code/getting_started/app/views/posts/_form.html.erb +0 -32
- data/guides/code/getting_started/app/views/posts/edit.html.erb +0 -6
- data/guides/code/getting_started/app/views/posts/index.html.erb +0 -27
- data/guides/code/getting_started/app/views/posts/new.html.erb +0 -5
- data/guides/code/getting_started/app/views/posts/show.html.erb +0 -31
- data/guides/code/getting_started/app/views/tags/_form.html.erb +0 -12
- data/guides/code/getting_started/config/application.rb +0 -59
- data/guides/code/getting_started/config/boot.rb +0 -6
- data/guides/code/getting_started/config/database.yml +0 -25
- data/guides/code/getting_started/config/environment.rb +0 -5
- data/guides/code/getting_started/config/environments/development.rb +0 -37
- data/guides/code/getting_started/config/environments/production.rb +0 -67
- data/guides/code/getting_started/config/environments/test.rb +0 -37
- data/guides/code/getting_started/config/initializers/backtrace_silencers.rb +0 -7
- data/guides/code/getting_started/config/initializers/inflections.rb +0 -15
- data/guides/code/getting_started/config/initializers/mime_types.rb +0 -5
- data/guides/code/getting_started/config/initializers/secret_token.rb +0 -7
- data/guides/code/getting_started/config/initializers/session_store.rb +0 -8
- data/guides/code/getting_started/config/initializers/wrap_parameters.rb +0 -14
- data/guides/code/getting_started/config/locales/en.yml +0 -5
- data/guides/code/getting_started/config/routes.rb +0 -64
- data/guides/code/getting_started/config.ru +0 -4
- data/guides/code/getting_started/db/migrate/20110901012504_create_posts.rb +0 -11
- data/guides/code/getting_started/db/migrate/20110901012815_create_comments.rb +0 -12
- data/guides/code/getting_started/db/migrate/20110901013701_create_tags.rb +0 -11
- data/guides/code/getting_started/db/schema.rb +0 -43
- data/guides/code/getting_started/db/seeds.rb +0 -7
- data/guides/code/getting_started/doc/README_FOR_APP +0 -2
- data/guides/code/getting_started/public/404.html +0 -26
- data/guides/code/getting_started/public/422.html +0 -26
- data/guides/code/getting_started/public/500.html +0 -25
- data/guides/code/getting_started/public/favicon.ico +0 -0
- data/guides/code/getting_started/public/robots.txt +0 -5
- data/guides/code/getting_started/script/rails +0 -6
- data/guides/code/getting_started/test/fixtures/comments.yml +0 -11
- data/guides/code/getting_started/test/fixtures/posts.yml +0 -11
- data/guides/code/getting_started/test/fixtures/tags.yml +0 -9
- data/guides/code/getting_started/test/functional/comments_controller_test.rb +0 -7
- data/guides/code/getting_started/test/functional/home_controller_test.rb +0 -9
- data/guides/code/getting_started/test/functional/posts_controller_test.rb +0 -49
- data/guides/code/getting_started/test/performance/browsing_test.rb +0 -12
- data/guides/code/getting_started/test/test_helper.rb +0 -13
- data/guides/code/getting_started/test/unit/comment_test.rb +0 -7
- data/guides/code/getting_started/test/unit/helpers/comments_helper_test.rb +0 -4
- data/guides/code/getting_started/test/unit/helpers/home_helper_test.rb +0 -4
- data/guides/code/getting_started/test/unit/helpers/posts_helper_test.rb +0 -4
- data/guides/code/getting_started/test/unit/post_test.rb +0 -7
- data/guides/code/getting_started/test/unit/tag_test.rb +0 -7
- data/guides/rails_guides/generator.rb +0 -310
- data/guides/rails_guides/helpers.rb +0 -45
- data/guides/rails_guides/indexer.rb +0 -69
- data/guides/rails_guides/levenshtein.rb +0 -31
- data/guides/rails_guides/textile_extensions.rb +0 -63
- data/guides/rails_guides.rb +0 -50
- data/guides/source/2_2_release_notes.textile +0 -422
- data/guides/source/2_3_release_notes.textile +0 -610
- data/guides/source/3_0_release_notes.textile +0 -595
- data/guides/source/3_1_release_notes.textile +0 -553
- data/guides/source/3_2_release_notes.textile +0 -540
- data/guides/source/_license.html.erb +0 -2
- data/guides/source/_welcome.html.erb +0 -19
- data/guides/source/action_controller_overview.textile +0 -820
- data/guides/source/action_mailer_basics.textile +0 -516
- data/guides/source/action_view_overview.textile +0 -1497
- data/guides/source/active_model_basics.textile +0 -205
- data/guides/source/active_record_basics.textile +0 -218
- data/guides/source/active_record_querying.textile +0 -1433
- data/guides/source/active_record_validations_callbacks.textile +0 -1283
- data/guides/source/active_resource_basics.textile +0 -120
- data/guides/source/active_support_core_extensions.textile +0 -3713
- data/guides/source/ajax_on_rails.textile +0 -267
- data/guides/source/api_documentation_guidelines.textile +0 -185
- data/guides/source/asset_pipeline.textile +0 -707
- data/guides/source/association_basics.textile +0 -1959
- data/guides/source/caching_with_rails.textile +0 -437
- data/guides/source/command_line.textile +0 -574
- data/guides/source/configuring.textile +0 -641
- data/guides/source/contributing_to_ruby_on_rails.textile +0 -448
- data/guides/source/credits.html.erb +0 -72
- data/guides/source/debugging_rails_applications.textile +0 -714
- data/guides/source/documents.yaml +0 -157
- data/guides/source/engines.textile +0 -618
- data/guides/source/form_helpers.textile +0 -798
- data/guides/source/generators.textile +0 -621
- data/guides/source/getting_started.textile +0 -1929
- data/guides/source/i18n.textile +0 -931
- data/guides/source/index.html.erb +0 -30
- data/guides/source/initialization.textile +0 -1116
- data/guides/source/kindle/KINDLE.md +0 -26
- data/guides/source/kindle/copyright.html.erb +0 -1
- data/guides/source/kindle/layout.html.erb +0 -27
- data/guides/source/kindle/rails_guides.opf.erb +0 -52
- data/guides/source/kindle/toc.html.erb +0 -24
- data/guides/source/kindle/toc.ncx.erb +0 -64
- data/guides/source/kindle/welcome.html.erb +0 -5
- data/guides/source/layout.html.erb +0 -124
- data/guides/source/layouts_and_rendering.textile +0 -1237
- data/guides/source/migrations.textile +0 -900
- data/guides/source/nested_model_forms.textile +0 -222
- data/guides/source/performance_testing.textile +0 -597
- data/guides/source/plugins.textile +0 -464
- data/guides/source/rails_application_templates.textile +0 -240
- data/guides/source/rails_on_rack.textile +0 -236
- data/guides/source/routing.textile +0 -885
- data/guides/source/ruby_on_rails_guides_guidelines.textile +0 -79
- data/guides/source/security.textile +0 -1004
- data/guides/source/testing.textile +0 -947
- data/guides/w3c_validator.rb +0 -91
- data/lib/rails/all.rb +0 -15
- data/lib/rails/application/bootstrap.rb +0 -73
- data/lib/rails/application/configuration.rb +0 -151
- data/lib/rails/application/finisher.rb +0 -98
- data/lib/rails/application/railties.rb +0 -13
- data/lib/rails/application/route_inspector.rb +0 -84
- data/lib/rails/application/routes_reloader.rb +0 -56
- data/lib/rails/application.rb +0 -320
- data/lib/rails/backtrace_cleaner.rb +0 -42
- data/lib/rails/cli.rb +0 -16
- data/lib/rails/code_statistics.rb +0 -118
- data/lib/rails/commands/application.rb +0 -36
- data/lib/rails/commands/benchmarker.rb +0 -34
- data/lib/rails/commands/console.rb +0 -55
- data/lib/rails/commands/dbconsole.rb +0 -123
- data/lib/rails/commands/destroy.rb +0 -10
- data/lib/rails/commands/generate.rb +0 -12
- data/lib/rails/commands/plugin.rb +0 -544
- data/lib/rails/commands/plugin_new.rb +0 -11
- data/lib/rails/commands/profiler.rb +0 -32
- data/lib/rails/commands/runner.rb +0 -54
- data/lib/rails/commands/server.rb +0 -100
- data/lib/rails/commands/update.rb +0 -9
- data/lib/rails/commands.rb +0 -104
- data/lib/rails/configuration.rb +0 -89
- data/lib/rails/console/app.rb +0 -36
- data/lib/rails/console/helpers.rb +0 -11
- data/lib/rails/engine/commands.rb +0 -43
- data/lib/rails/engine/configuration.rb +0 -84
- data/lib/rails/engine/railties.rb +0 -33
- data/lib/rails/engine.rb +0 -657
- data/lib/rails/generators/actions.rb +0 -325
- data/lib/rails/generators/active_model.rb +0 -78
- data/lib/rails/generators/app_base.rb +0 -266
- data/lib/rails/generators/base.rb +0 -390
- data/lib/rails/generators/css/assets/assets_generator.rb +0 -13
- data/lib/rails/generators/css/assets/templates/stylesheet.css +0 -4
- data/lib/rails/generators/css/scaffold/scaffold_generator.rb +0 -16
- data/lib/rails/generators/erb/controller/controller_generator.rb +0 -20
- data/lib/rails/generators/erb/controller/templates/view.html.erb +0 -2
- data/lib/rails/generators/erb/mailer/mailer_generator.rb +0 -13
- data/lib/rails/generators/erb/mailer/templates/view.text.erb +0 -3
- data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +0 -29
- data/lib/rails/generators/erb/scaffold/templates/_form.html.erb +0 -23
- data/lib/rails/generators/erb/scaffold/templates/edit.html.erb +0 -6
- data/lib/rails/generators/erb/scaffold/templates/index.html.erb +0 -27
- data/lib/rails/generators/erb/scaffold/templates/new.html.erb +0 -5
- data/lib/rails/generators/erb/scaffold/templates/show.html.erb +0 -12
- data/lib/rails/generators/erb.rb +0 -21
- data/lib/rails/generators/generated_attribute.rb +0 -107
- data/lib/rails/generators/js/assets/assets_generator.rb +0 -13
- data/lib/rails/generators/js/assets/templates/javascript.js +0 -2
- data/lib/rails/generators/migration.rb +0 -68
- data/lib/rails/generators/named_base.rb +0 -202
- data/lib/rails/generators/rails/app/USAGE +0 -15
- data/lib/rails/generators/rails/app/app_generator.rb +0 -312
- data/lib/rails/generators/rails/app/templates/Gemfile +0 -21
- data/lib/rails/generators/rails/app/templates/README +0 -261
- data/lib/rails/generators/rails/app/templates/Rakefile +0 -7
- data/lib/rails/generators/rails/app/templates/app/assets/images/rails.png +0 -0
- data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +0 -17
- data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +0 -13
- data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb +0 -3
- data/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb +0 -2
- data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/app/models/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +0 -14
- data/lib/rails/generators/rails/app/templates/config/application.rb +0 -68
- data/lib/rails/generators/rails/app/templates/config/boot.rb +0 -6
- data/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml +0 -31
- data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml +0 -86
- data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +0 -62
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +0 -33
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +0 -43
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +0 -20
- data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +0 -54
- data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +0 -39
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +0 -55
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml +0 -25
- data/lib/rails/generators/rails/app/templates/config/environment.rb +0 -5
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +0 -41
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +0 -73
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +0 -39
- data/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb +0 -7
- data/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb +0 -15
- data/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb +0 -5
- data/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt +0 -7
- data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +0 -8
- data/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt +0 -16
- data/lib/rails/generators/rails/app/templates/config/locales/en.yml +0 -5
- data/lib/rails/generators/rails/app/templates/config/routes.rb +0 -58
- data/lib/rails/generators/rails/app/templates/config.ru +0 -4
- data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +0 -7
- data/lib/rails/generators/rails/app/templates/doc/README_FOR_APP +0 -2
- data/lib/rails/generators/rails/app/templates/gitignore +0 -15
- data/lib/rails/generators/rails/app/templates/public/404.html +0 -26
- data/lib/rails/generators/rails/app/templates/public/422.html +0 -26
- data/lib/rails/generators/rails/app/templates/public/500.html +0 -25
- data/lib/rails/generators/rails/app/templates/public/robots.txt +0 -5
- data/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/script/openskies +0 -5
- data/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/test/functional/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/test/integration/.empty_directory +0 -0
- data/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb +0 -12
- data/lib/rails/generators/rails/app/templates/test/test_helper.rb +0 -15
- data/lib/rails/generators/rails/app/templates/test/unit/.empty_directory +0 -0
- data/lib/rails/generators/rails/assets/USAGE +0 -20
- data/lib/rails/generators/rails/assets/assets_generator.rb +0 -25
- data/lib/rails/generators/rails/assets/templates/javascript.js +0 -2
- data/lib/rails/generators/rails/assets/templates/stylesheet.css +0 -4
- data/lib/rails/generators/rails/controller/USAGE +0 -18
- data/lib/rails/generators/rails/controller/controller_generator.rb +0 -20
- data/lib/rails/generators/rails/controller/templates/controller.rb +0 -13
- data/lib/rails/generators/rails/generator/USAGE +0 -12
- data/lib/rails/generators/rails/generator/generator_generator.rb +0 -25
- data/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt +0 -3
- data/lib/rails/generators/rails/generator/templates/USAGE.tt +0 -8
- data/lib/rails/generators/rails/generator/templates/templates/.empty_directory +0 -0
- data/lib/rails/generators/rails/helper/USAGE +0 -17
- data/lib/rails/generators/rails/helper/helper_generator.rb +0 -13
- data/lib/rails/generators/rails/helper/templates/helper.rb +0 -4
- data/lib/rails/generators/rails/integration_test/USAGE +0 -10
- data/lib/rails/generators/rails/integration_test/integration_test_generator.rb +0 -7
- data/lib/rails/generators/rails/migration/USAGE +0 -29
- data/lib/rails/generators/rails/migration/migration_generator.rb +0 -8
- data/lib/rails/generators/rails/model/USAGE +0 -45
- data/lib/rails/generators/rails/model/model_generator.rb +0 -8
- data/lib/rails/generators/rails/observer/USAGE +0 -12
- data/lib/rails/generators/rails/observer/observer_generator.rb +0 -7
- data/lib/rails/generators/rails/performance_test/USAGE +0 -10
- data/lib/rails/generators/rails/performance_test/performance_test_generator.rb +0 -7
- data/lib/rails/generators/rails/plugin_new/USAGE +0 -10
- data/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +0 -318
- data/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +0 -29
- data/lib/rails/generators/rails/plugin_new/templates/Gemfile +0 -23
- data/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE +0 -20
- data/lib/rails/generators/rails/plugin_new/templates/README.rdoc +0 -3
- data/lib/rails/generators/rails/plugin_new/templates/Rakefile +0 -31
- data/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt +0 -4
- data/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt +0 -4
- data/lib/rails/generators/rails/plugin_new/templates/app/mailers/.empty_directory +0 -0
- data/lib/rails/generators/rails/plugin_new/templates/app/models/.empty_directory +0 -0
- data/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/%name%/application.html.erb.tt +0 -14
- data/lib/rails/generators/rails/plugin_new/templates/config/routes.rb +0 -6
- data/lib/rails/generators/rails/plugin_new/templates/gitignore +0 -7
- data/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb +0 -7
- data/lib/rails/generators/rails/plugin_new/templates/lib/%name%/version.rb +0 -3
- data/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb +0 -6
- data/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake +0 -4
- data/lib/rails/generators/rails/plugin_new/templates/rails/application.rb +0 -18
- data/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb +0 -10
- data/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb +0 -4
- data/lib/rails/generators/rails/plugin_new/templates/script/rails.tt +0 -7
- data/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb +0 -7
- data/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb +0 -12
- data/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb +0 -15
- data/lib/rails/generators/rails/resource/USAGE +0 -23
- data/lib/rails/generators/rails/resource/resource_generator.rb +0 -20
- data/lib/rails/generators/rails/resource_route/resource_route_generator.rb +0 -50
- data/lib/rails/generators/rails/scaffold/USAGE +0 -35
- data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +0 -23
- data/lib/rails/generators/rails/scaffold/templates/scaffold.css +0 -56
- data/lib/rails/generators/rails/scaffold_controller/USAGE +0 -19
- data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +0 -25
- data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +0 -89
- data/lib/rails/generators/rails/session_migration/USAGE +0 -8
- data/lib/rails/generators/rails/session_migration/session_migration_generator.rb +0 -8
- data/lib/rails/generators/rails/task/USAGE +0 -9
- data/lib/rails/generators/rails/task/task_generator.rb +0 -12
- data/lib/rails/generators/rails/task/templates/task.rb +0 -8
- data/lib/rails/generators/resource_helpers.rb +0 -80
- data/lib/rails/generators/test_case.rb +0 -247
- data/lib/rails/generators/test_unit/controller/controller_generator.rb +0 -15
- data/lib/rails/generators/test_unit/controller/templates/functional_test.rb +0 -19
- data/lib/rails/generators/test_unit/helper/helper_generator.rb +0 -13
- data/lib/rails/generators/test_unit/helper/templates/helper_test.rb +0 -6
- data/lib/rails/generators/test_unit/integration/integration_generator.rb +0 -13
- data/lib/rails/generators/test_unit/integration/templates/integration_test.rb +0 -7
- data/lib/rails/generators/test_unit/mailer/mailer_generator.rb +0 -14
- data/lib/rails/generators/test_unit/mailer/templates/functional_test.rb +0 -21
- data/lib/rails/generators/test_unit/model/model_generator.rb +0 -24
- data/lib/rails/generators/test_unit/model/templates/fixtures.yml +0 -23
- data/lib/rails/generators/test_unit/model/templates/unit_test.rb +0 -9
- data/lib/rails/generators/test_unit/observer/observer_generator.rb +0 -13
- data/lib/rails/generators/test_unit/observer/templates/unit_test.rb +0 -9
- data/lib/rails/generators/test_unit/performance/performance_generator.rb +0 -13
- data/lib/rails/generators/test_unit/performance/templates/performance_test.rb +0 -12
- data/lib/rails/generators/test_unit/plugin/plugin_generator.rb +0 -13
- data/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +0 -7
- data/lib/rails/generators/test_unit/plugin/templates/test_helper.rb +0 -3
- data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +0 -38
- data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +0 -51
- data/lib/rails/generators/test_unit.rb +0 -8
- data/lib/rails/generators.rb +0 -339
- data/lib/rails/info.rb +0 -116
- data/lib/rails/info_controller.rb +0 -15
- data/lib/rails/initializable.rb +0 -89
- data/lib/rails/paths.rb +0 -211
- data/lib/rails/performance_test_help.rb +0 -3
- data/lib/rails/plugin.rb +0 -92
- data/lib/rails/rack/debugger.rb +0 -24
- data/lib/rails/rack/log_tailer.rb +0 -34
- data/lib/rails/rack/logger.rb +0 -60
- data/lib/rails/rack.rb +0 -7
- data/lib/rails/railtie/configurable.rb +0 -35
- data/lib/rails/railtie/configuration.rb +0 -90
- data/lib/rails/railtie.rb +0 -202
- data/lib/rails/ruby_version_check.rb +0 -23
- data/lib/rails/rubyprof_ext.rb +0 -35
- data/lib/rails/script_rails_loader.rb +0 -29
- data/lib/rails/source_annotation_extractor.rb +0 -104
- data/lib/rails/tasks/annotations.rake +0 -20
- data/lib/rails/tasks/documentation.rake +0 -155
- data/lib/rails/tasks/engine.rake +0 -72
- data/lib/rails/tasks/framework.rake +0 -76
- data/lib/rails/tasks/log.rake +0 -9
- data/lib/rails/tasks/middleware.rake +0 -7
- data/lib/rails/tasks/misc.rake +0 -67
- data/lib/rails/tasks/routes.rake +0 -9
- data/lib/rails/tasks/statistics.rake +0 -16
- data/lib/rails/tasks/tmp.rake +0 -37
- data/lib/rails/tasks.rb +0 -16
- data/lib/rails/test_help.rb +0 -56
- data/lib/rails/test_unit/railtie.rb +0 -15
- data/lib/rails/test_unit/sub_test_task.rb +0 -8
- data/lib/rails/test_unit/testing.rake +0 -146
- data/lib/rails.rb +0 -121
- data/lib/version.rb +0 -16
@@ -1,900 +0,0 @@
|
|
1
|
-
h2. Migrations
|
2
|
-
|
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:
|
22
|
-
|
23
|
-
* The generators you can use to create them
|
24
|
-
* The methods Active Record provides to manipulate your database
|
25
|
-
* The Rake tasks that manipulate them
|
26
|
-
* How they relate to +schema.rb+
|
27
|
-
|
28
|
-
endprologue.
|
29
|
-
|
30
|
-
h3. Anatomy of a Migration
|
31
|
-
|
32
|
-
Before we dive into the details of a migration, here are a few examples of the
|
33
|
-
sorts of things you can do:
|
34
|
-
|
35
|
-
<ruby>
|
36
|
-
class CreateProducts < ActiveRecord::Migration
|
37
|
-
def up
|
38
|
-
create_table :products do |t|
|
39
|
-
t.string :name
|
40
|
-
t.text :description
|
41
|
-
|
42
|
-
t.timestamps
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def down
|
47
|
-
drop_table :products
|
48
|
-
end
|
49
|
-
end
|
50
|
-
</ruby>
|
51
|
-
|
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.
|
58
|
-
|
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:
|
61
|
-
|
62
|
-
<ruby>
|
63
|
-
class AddReceiveNewsletterToUsers < ActiveRecord::Migration
|
64
|
-
def up
|
65
|
-
change_table :users do |t|
|
66
|
-
t.boolean :receive_newsletter, :default => false
|
67
|
-
end
|
68
|
-
User.update_all ["receive_newsletter = ?", true]
|
69
|
-
end
|
70
|
-
|
71
|
-
def down
|
72
|
-
remove_column :users, :receive_newsletter
|
73
|
-
end
|
74
|
-
end
|
75
|
-
</ruby>
|
76
|
-
|
77
|
-
NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in
|
78
|
-
your migrations.
|
79
|
-
|
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.
|
84
|
-
|
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.
|
89
|
-
|
90
|
-
<ruby>
|
91
|
-
class CreateProducts < ActiveRecord::Migration
|
92
|
-
def change
|
93
|
-
create_table :products do |t|
|
94
|
-
t.string :name
|
95
|
-
t.text :description
|
96
|
-
|
97
|
-
t.timestamps
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
</ruby>
|
102
|
-
|
103
|
-
h4. Migrations are Classes
|
104
|
-
|
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).
|
108
|
-
|
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):
|
111
|
-
|
112
|
-
* +add_column+
|
113
|
-
* +add_index+
|
114
|
-
* +change_column+
|
115
|
-
* +change_table+
|
116
|
-
* +create_table+
|
117
|
-
* +drop_table+
|
118
|
-
* +remove_column+
|
119
|
-
* +remove_index+
|
120
|
-
* +rename_column+
|
121
|
-
|
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).
|
128
|
-
|
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.
|
134
|
-
|
135
|
-
h4. What's in a Name
|
136
|
-
|
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+.
|
156
|
-
|
157
|
-
<ruby>
|
158
|
-
config.active_record.timestamped_migrations = false
|
159
|
-
</ruby>
|
160
|
-
|
161
|
-
The combination of timestamps and recording which migrations have been run
|
162
|
-
allows Rails to handle common situations that occur with multiple developers.
|
163
|
-
|
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.
|
168
|
-
|
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.
|
172
|
-
|
173
|
-
h4. Changing Migrations
|
174
|
-
|
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.
|
180
|
-
|
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.
|
188
|
-
|
189
|
-
h4. Supported Types
|
190
|
-
|
191
|
-
Active Record supports the following database column types:
|
192
|
-
|
193
|
-
* +:binary+
|
194
|
-
* +:boolean+
|
195
|
-
* +:date+
|
196
|
-
* +:datetime+
|
197
|
-
* +:decimal+
|
198
|
-
* +:float+
|
199
|
-
* +:integer+
|
200
|
-
* +:primary_key+
|
201
|
-
* +:string+
|
202
|
-
* +:text+
|
203
|
-
* +:time+
|
204
|
-
* +:timestamp+
|
205
|
-
|
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
|
210
|
-
|
211
|
-
<ruby>
|
212
|
-
create_table :products do |t|
|
213
|
-
t.column :name, 'polygon', :null => false
|
214
|
-
end
|
215
|
-
</ruby>
|
216
|
-
|
217
|
-
This may however hinder portability to other databases.
|
218
|
-
|
219
|
-
h3. Creating a Migration
|
220
|
-
|
221
|
-
h4. Creating a Model
|
222
|
-
|
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
|
227
|
-
|
228
|
-
<shell>
|
229
|
-
$ rails generate model Product name:string description:text
|
230
|
-
</shell>
|
231
|
-
|
232
|
-
will create a migration that looks like this
|
233
|
-
|
234
|
-
<ruby>
|
235
|
-
class CreateProducts < ActiveRecord::Migration
|
236
|
-
def change
|
237
|
-
create_table :products do |t|
|
238
|
-
t.string :name
|
239
|
-
t.text :description
|
240
|
-
|
241
|
-
t.timestamps
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
</ruby>
|
246
|
-
|
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).
|
251
|
-
|
252
|
-
h4. Creating a Standalone Migration
|
253
|
-
|
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:
|
256
|
-
|
257
|
-
<shell>
|
258
|
-
$ rails generate migration AddPartNumberToProducts
|
259
|
-
</shell>
|
260
|
-
|
261
|
-
This will create an empty but appropriately named migration:
|
262
|
-
|
263
|
-
<ruby>
|
264
|
-
class AddPartNumberToProducts < ActiveRecord::Migration
|
265
|
-
def change
|
266
|
-
end
|
267
|
-
end
|
268
|
-
</ruby>
|
269
|
-
|
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.
|
273
|
-
|
274
|
-
<shell>
|
275
|
-
$ rails generate migration AddPartNumberToProducts part_number:string
|
276
|
-
</shell>
|
277
|
-
|
278
|
-
will generate
|
279
|
-
|
280
|
-
<ruby>
|
281
|
-
class AddPartNumberToProducts < ActiveRecord::Migration
|
282
|
-
def change
|
283
|
-
add_column :products, :part_number, :string
|
284
|
-
end
|
285
|
-
end
|
286
|
-
</ruby>
|
287
|
-
|
288
|
-
Similarly,
|
289
|
-
|
290
|
-
<shell>
|
291
|
-
$ rails generate migration RemovePartNumberFromProducts part_number:string
|
292
|
-
</shell>
|
293
|
-
|
294
|
-
generates
|
295
|
-
|
296
|
-
<ruby>
|
297
|
-
class RemovePartNumberFromProducts < ActiveRecord::Migration
|
298
|
-
def up
|
299
|
-
remove_column :products, :part_number
|
300
|
-
end
|
301
|
-
|
302
|
-
def down
|
303
|
-
add_column :products, :part_number, :string
|
304
|
-
end
|
305
|
-
end
|
306
|
-
</ruby>
|
307
|
-
|
308
|
-
You are not limited to one magically generated column, for example
|
309
|
-
|
310
|
-
<shell>
|
311
|
-
$ rails generate migration AddDetailsToProducts part_number:string price:decimal
|
312
|
-
</shell>
|
313
|
-
|
314
|
-
generates
|
315
|
-
|
316
|
-
<ruby>
|
317
|
-
class AddDetailsToProducts < ActiveRecord::Migration
|
318
|
-
def change
|
319
|
-
add_column :products, :part_number, :string
|
320
|
-
add_column :products, :price, :decimal
|
321
|
-
end
|
322
|
-
end
|
323
|
-
</ruby>
|
324
|
-
|
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.
|
328
|
-
|
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.
|
332
|
-
|
333
|
-
h3. Writing a Migration
|
334
|
-
|
335
|
-
Once you have created your migration using one of the generators it's time to
|
336
|
-
get to work!
|
337
|
-
|
338
|
-
h4. Creating a Table
|
339
|
-
|
340
|
-
Migration method +create_table+ will be one of your workhorses. A typical use
|
341
|
-
would be
|
342
|
-
|
343
|
-
<ruby>
|
344
|
-
create_table :products do |t|
|
345
|
-
t.string :name
|
346
|
-
end
|
347
|
-
</ruby>
|
348
|
-
|
349
|
-
which creates a +products+ table with a column called +name+ (and as discussed
|
350
|
-
below, an implicit +id+ column).
|
351
|
-
|
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
|
354
|
-
|
355
|
-
<ruby>
|
356
|
-
create_table :products do |t|
|
357
|
-
t.column :name, :string, :null => false
|
358
|
-
end
|
359
|
-
</ruby>
|
360
|
-
|
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.
|
364
|
-
|
365
|
-
<ruby>
|
366
|
-
create_table :products do |t|
|
367
|
-
t.string :name, :null => false
|
368
|
-
end
|
369
|
-
</ruby>
|
370
|
-
|
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,
|
377
|
-
|
378
|
-
<ruby>
|
379
|
-
create_table :products, :options => "ENGINE=BLACKHOLE" do |t|
|
380
|
-
t.string :name, :null => false
|
381
|
-
end
|
382
|
-
</ruby>
|
383
|
-
|
384
|
-
will append +ENGINE=BLACKHOLE+ to the SQL statement used to create the table
|
385
|
-
(when using MySQL, the default is +ENGINE=InnoDB+).
|
386
|
-
|
387
|
-
h4. Changing Tables
|
388
|
-
|
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
|
392
|
-
|
393
|
-
<ruby>
|
394
|
-
change_table :products do |t|
|
395
|
-
t.remove :description, :name
|
396
|
-
t.string :part_number
|
397
|
-
t.index :part_number
|
398
|
-
t.rename :upccode, :upc_code
|
399
|
-
end
|
400
|
-
</ruby>
|
401
|
-
|
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.
|
404
|
-
|
405
|
-
h4. Special Helpers
|
406
|
-
|
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:
|
410
|
-
|
411
|
-
<ruby>
|
412
|
-
create_table :products do |t|
|
413
|
-
t.timestamps
|
414
|
-
end
|
415
|
-
</ruby>
|
416
|
-
|
417
|
-
will create a new products table with those two columns (plus the +id+ column)
|
418
|
-
whereas
|
419
|
-
|
420
|
-
<ruby>
|
421
|
-
change_table :products do |t|
|
422
|
-
t.timestamps
|
423
|
-
end
|
424
|
-
</ruby>
|
425
|
-
adds those columns to an existing table.
|
426
|
-
|
427
|
-
Another helper is called +references+ (also available as +belongs_to+). In its
|
428
|
-
simplest form it just adds some readability.
|
429
|
-
|
430
|
-
<ruby>
|
431
|
-
create_table :products do |t|
|
432
|
-
t.references :category
|
433
|
-
end
|
434
|
-
</ruby>
|
435
|
-
|
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:
|
440
|
-
|
441
|
-
<ruby>
|
442
|
-
create_table :products do |t|
|
443
|
-
t.references :attachment, :polymorphic => {:default => 'Photo'}
|
444
|
-
end
|
445
|
-
</ruby>
|
446
|
-
|
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.
|
453
|
-
|
454
|
-
If the helpers provided by Active Record aren't enough you can use the +execute+
|
455
|
-
method to execute arbitrary SQL.
|
456
|
-
|
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+).
|
466
|
-
|
467
|
-
h4. Using the +change+ Method
|
468
|
-
|
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:
|
472
|
-
|
473
|
-
* +add_column+
|
474
|
-
* +add_index+
|
475
|
-
* +add_timestamps+
|
476
|
-
* +create_table+
|
477
|
-
* +remove_timestamps+
|
478
|
-
* +rename_column+
|
479
|
-
* +rename_index+
|
480
|
-
* +rename_table+
|
481
|
-
|
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.
|
484
|
-
|
485
|
-
h4. Using the +up+/+down+ Methods
|
486
|
-
|
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,
|
493
|
-
|
494
|
-
<ruby>
|
495
|
-
class ExampleMigration < ActiveRecord::Migration
|
496
|
-
def up
|
497
|
-
create_table :products do |t|
|
498
|
-
t.references :category
|
499
|
-
end
|
500
|
-
#add a foreign key
|
501
|
-
execute <<-SQL
|
502
|
-
ALTER TABLE products
|
503
|
-
ADD CONSTRAINT fk_products_categories
|
504
|
-
FOREIGN KEY (category_id)
|
505
|
-
REFERENCES categories(id)
|
506
|
-
SQL
|
507
|
-
add_column :users, :home_page_url, :string
|
508
|
-
rename_column :users, :email, :email_address
|
509
|
-
end
|
510
|
-
|
511
|
-
def down
|
512
|
-
rename_column :users, :email_address, :email
|
513
|
-
remove_column :users, :home_page_url
|
514
|
-
execute <<-SQL
|
515
|
-
ALTER TABLE products
|
516
|
-
DROP FOREIGN KEY fk_products_categories
|
517
|
-
SQL
|
518
|
-
drop_table :products
|
519
|
-
end
|
520
|
-
end
|
521
|
-
</ruby>
|
522
|
-
|
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.
|
528
|
-
|
529
|
-
h3. Running Migrations
|
530
|
-
|
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.
|
539
|
-
|
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.
|
542
|
-
|
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
|
547
|
-
|
548
|
-
<shell>
|
549
|
-
$ rake db:migrate VERSION=20080906120000
|
550
|
-
</shell>
|
551
|
-
|
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.
|
557
|
-
|
558
|
-
h4. Rolling Back
|
559
|
-
|
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
|
563
|
-
|
564
|
-
<shell>
|
565
|
-
$ rake db:rollback
|
566
|
-
</shell>
|
567
|
-
|
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:
|
570
|
-
|
571
|
-
<shell>
|
572
|
-
$ rake db:rollback STEP=3
|
573
|
-
</shell>
|
574
|
-
|
575
|
-
will run the +down+ method from the last 3 migrations.
|
576
|
-
|
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
|
580
|
-
|
581
|
-
<shell>
|
582
|
-
$ rake db:migrate:redo STEP=3
|
583
|
-
</shell>
|
584
|
-
|
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.
|
588
|
-
|
589
|
-
h4. Resetting the database
|
590
|
-
|
591
|
-
The +rake db:reset+ task will drop the database, recreate it and load the
|
592
|
-
current schema into it.
|
593
|
-
|
594
|
-
NOTE: This is not the same as running all the migrations - see the section on
|
595
|
-
"schema.rb":#schema-dumping-and-you.
|
596
|
-
|
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,
|
603
|
-
|
604
|
-
<shell>
|
605
|
-
$ rake db:migrate:up VERSION=20080906120000
|
606
|
-
</shell>
|
607
|
-
|
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.
|
612
|
-
|
613
|
-
h4. Changing the output of running migrations
|
614
|
-
|
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
|
617
|
-
|
618
|
-
<shell>
|
619
|
-
== CreateProducts: migrating =================================================
|
620
|
-
-- create_table(:products)
|
621
|
-
-> 0.0028s
|
622
|
-
== CreateProducts: migrated (0.0028s) ========================================
|
623
|
-
</shell>
|
624
|
-
|
625
|
-
Several methods are provided in migrations that allow you to control all this:
|
626
|
-
|
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.|
|
636
|
-
|
637
|
-
For example, this migration
|
638
|
-
|
639
|
-
<ruby>
|
640
|
-
class CreateProducts < ActiveRecord::Migration
|
641
|
-
def change
|
642
|
-
suppress_messages do
|
643
|
-
create_table :products do |t|
|
644
|
-
t.string :name
|
645
|
-
t.text :description
|
646
|
-
t.timestamps
|
647
|
-
end
|
648
|
-
end
|
649
|
-
say "Created a table"
|
650
|
-
suppress_messages {add_index :products, :name}
|
651
|
-
say "and an index!", true
|
652
|
-
say_with_time 'Waiting for a while' do
|
653
|
-
sleep 10
|
654
|
-
250
|
655
|
-
end
|
656
|
-
end
|
657
|
-
end
|
658
|
-
</ruby>
|
659
|
-
|
660
|
-
generates the following output
|
661
|
-
|
662
|
-
<shell>
|
663
|
-
== CreateProducts: migrating =================================================
|
664
|
-
-- Created a table
|
665
|
-
-> and an index!
|
666
|
-
-- Waiting for a while
|
667
|
-
-> 10.0013s
|
668
|
-
-> 250 rows
|
669
|
-
== CreateProducts: migrated (10.0054s) =======================================
|
670
|
-
</shell>
|
671
|
-
|
672
|
-
If you want Active Record to not output anything, then running +rake db:migrate
|
673
|
-
VERBOSE=false+ will suppress all output.
|
674
|
-
|
675
|
-
h3. Using Models in Your Migrations
|
676
|
-
|
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.
|
680
|
-
|
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.
|
684
|
-
|
685
|
-
Consider this example, where Alice and Bob are working on the same code base
|
686
|
-
which contains a +Product+ model:
|
687
|
-
|
688
|
-
Bob goes on vacation.
|
689
|
-
|
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.
|
693
|
-
|
694
|
-
<ruby>
|
695
|
-
# db/migrate/20100513121110_add_flag_to_product.rb
|
696
|
-
|
697
|
-
class AddFlagToProduct < ActiveRecord::Migration
|
698
|
-
def change
|
699
|
-
add_column :products, :flag, :boolean
|
700
|
-
Product.all.each do |product|
|
701
|
-
product.update_attributes!(:flag => 'false')
|
702
|
-
end
|
703
|
-
end
|
704
|
-
end
|
705
|
-
</ruby>
|
706
|
-
|
707
|
-
<ruby>
|
708
|
-
# app/model/product.rb
|
709
|
-
|
710
|
-
class Product < ActiveRecord::Base
|
711
|
-
validates :flag, :presence => true
|
712
|
-
end
|
713
|
-
</ruby>
|
714
|
-
|
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.
|
718
|
-
|
719
|
-
<ruby>
|
720
|
-
# db/migrate/20100515121110_add_fuzz_to_product.rb
|
721
|
-
|
722
|
-
class AddFuzzToProduct < ActiveRecord::Migration
|
723
|
-
def change
|
724
|
-
add_column :products, :fuzz, :string
|
725
|
-
Product.all.each do |product|
|
726
|
-
product.update_attributes! :fuzz => 'fuzzy'
|
727
|
-
end
|
728
|
-
end
|
729
|
-
end
|
730
|
-
</ruby>
|
731
|
-
|
732
|
-
<ruby>
|
733
|
-
# app/model/product.rb
|
734
|
-
|
735
|
-
class Product < ActiveRecord::Base
|
736
|
-
validates :flag, :fuzz, :presence => true
|
737
|
-
end
|
738
|
-
</ruby>
|
739
|
-
|
740
|
-
Both migrations work for Alice.
|
741
|
-
|
742
|
-
Bob comes back from vacation and:
|
743
|
-
|
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.
|
748
|
-
|
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:
|
752
|
-
|
753
|
-
<plain>
|
754
|
-
rake aborted!
|
755
|
-
An error has occurred, this and all later migrations canceled:
|
756
|
-
|
757
|
-
undefined method `fuzz' for #<Product:0x000001049b14a0>
|
758
|
-
</plain>
|
759
|
-
|
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.
|
762
|
-
|
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.
|
766
|
-
|
767
|
-
If Alice had done this instead, there would have been no problem:
|
768
|
-
|
769
|
-
<ruby>
|
770
|
-
# db/migrate/20100513121110_add_flag_to_product.rb
|
771
|
-
|
772
|
-
class AddFlagToProduct < ActiveRecord::Migration
|
773
|
-
class Product < ActiveRecord::Base
|
774
|
-
end
|
775
|
-
|
776
|
-
def change
|
777
|
-
add_column :products, :flag, :integer
|
778
|
-
Product.reset_column_information
|
779
|
-
Product.all.each do |product|
|
780
|
-
product.update_attributes!(:flag => false)
|
781
|
-
end
|
782
|
-
end
|
783
|
-
end
|
784
|
-
</ruby>
|
785
|
-
|
786
|
-
<ruby>
|
787
|
-
# db/migrate/20100515121110_add_fuzz_to_product.rb
|
788
|
-
|
789
|
-
class AddFuzzToProduct < ActiveRecord::Migration
|
790
|
-
class Product < ActiveRecord::Base
|
791
|
-
end
|
792
|
-
|
793
|
-
def change
|
794
|
-
add_column :products, :fuzz, :string
|
795
|
-
Product.reset_column_information
|
796
|
-
Product.all.each do |product|
|
797
|
-
product.update_attributes!(:fuzz => 'fuzzy')
|
798
|
-
end
|
799
|
-
end
|
800
|
-
end
|
801
|
-
</ruby>
|
802
|
-
|
803
|
-
h3. Schema Dumping and You
|
804
|
-
|
805
|
-
h4. What are Schema Files for?
|
806
|
-
|
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.
|
811
|
-
|
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.
|
815
|
-
|
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/structure.sql+) and then
|
818
|
-
loaded into the test database.
|
819
|
-
|
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.
|
827
|
-
|
828
|
-
h4. Types of Schema Dumps
|
829
|
-
|
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+.
|
833
|
-
|
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:
|
836
|
-
|
837
|
-
<ruby>
|
838
|
-
ActiveRecord::Schema.define(:version => 20080906171750) do
|
839
|
-
create_table "authors", :force => true do |t|
|
840
|
-
t.string "name"
|
841
|
-
t.datetime "created_at"
|
842
|
-
t.datetime "updated_at"
|
843
|
-
end
|
844
|
-
|
845
|
-
create_table "products", :force => true do |t|
|
846
|
-
t.string "name"
|
847
|
-
t.text "description"
|
848
|
-
t.datetime "created_at"
|
849
|
-
t.datetime "updated_at"
|
850
|
-
t.string "part_number"
|
851
|
-
end
|
852
|
-
end
|
853
|
-
</ruby>
|
854
|
-
|
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.
|
876
|
-
|
877
|
-
h4. Schema Dumps and Source Control
|
878
|
-
|
879
|
-
Because schema dumps are the authoritative source for your database schema, it
|
880
|
-
is strongly recommended that you check them into source control.
|
881
|
-
|
882
|
-
h3. Active Record and Referential Integrity
|
883
|
-
|
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+).
|