Ruby on Rails Backup Database and Run Migration Again

Migrations

Migrations are a user-friendly mode for you lot to modify your database in a structured and organized manner. You could edit fragments of SQL by paw but you lot would so be responsible for telling other developers that they need to go and run them. Yous'd also take to keep track of which changes need to be run against the production machines adjacent time y'all deploy.

Active Record tracks which migrations take already been run so all you have to do is update your source and run rake db:migrate. Active Record will work out which migrations should be run. Information technology volition also update your db/schema.rb file to match the structure of your database.

Migrations besides allow you to describe these transformations using Reddish. The great affair most this is that (similar about of Active Record's functionality) it is database contained: yous don't need to worry well-nigh the precise syntax of CREATE Tabular array any more than you worry about variations on SELECT * (y'all can drop down to raw SQL for database specific features). For instance you could use SQLite3 in development, but MySQL in product.

In this guide, you'll learn all well-nigh migrations including:

  • The generators you lot can apply to create them
  • The methods Active Tape provides to manipulate your database
  • The Rake tasks that manipulate them
  • How they relate to schema.rb

Capacity

  1. Anatomy of a Migration
    • Migrations are Classes
    • What's in a Proper name
    • Changing Migrations
    • Supported Types
  2. Creating a Migration
    • Creating a Model
    • Creating a Standalone Migration
  3. Writing a Migration
    • Creating a Table
    • Irresolute Tables
    • Special Helpers
    • Using the alter Method
    • Using the up/down Methods
  4. Running Migrations
    • Rolling Back
    • Resetting the database
    • Running specific migrations
    • Changing the output of running migrations
  5. Using Models in Your Migrations
  6. Schema Dumping and Y'all
    • What are Schema Files for?
    • Types of Schema Dumps
    • Schema Dumps and Source Command
  7. Active Record and Referential Integrity

1 Anatomy of a Migration

Earlier we dive into the details of a migration, hither are a few examples of the sorts of things you can do:

grade CreateProducts < ActiveRecord::Migration   def up     create_table :products do |t|       t.cord :proper name       t.text :description        t.timestamps     end   stop    def down     drop_table :products   cease end          

This migration adds a tabular array called products with a string column called name and a text column chosen description. A primary fundamental column called id will also be added, however since this is the default nosotros practise not need to inquire for this. The timestamp columns created_at and updated_at which Agile Record populates automatically will too be added. Reversing this migration is every bit uncomplicated as dropping the tabular array.

Migrations are not express to changing the schema. Yous tin also use them to fix bad data in the database or populate new fields:

class AddReceiveNewsletterToUsers < ActiveRecord::Migration   def upwards     change_table :users do |t|       t.boolean :receive_newsletter, :default => false     finish     User.update_all ["receive_newsletter = ?", true]   terminate    def down     remove_column :users, :receive_newsletter   stop end          

Some caveats apply to using models in your migrations.

This migration adds a receive_newsletter column to the users tabular array. We want it to default to false for new users, merely existing users are considered to have already opted in, then nosotros use the User model to fix the flag to true for existing users.

Rails 3.i makes migrations smarter past providing a new alter method. This method is preferred for writing constructive migrations (adding columns or tables). The migration knows how to migrate your database and reverse it when the migration is rolled back without the demand to write a separate down method.

class CreateProducts < ActiveRecord::Migration   def alter     create_table :products practise |t|       t.string :name       t.text :description        t.timestamps     end   cease cease          

1.one Migrations are Classes

A migration is a bracket of ActiveRecord::Migration that implements 2 methods: up (perform the required transformations) and down (revert them).

Active Record provides methods that perform common information definition tasks in a database independent way (yous'll read about them in detail later):

  • add_column
  • add_index
  • change_column
  • change_table
  • create_table
  • drop_table
  • remove_column
  • remove_index
  • rename_column

If you need to perform tasks specific to your database (for instance create a foreign key constraint) then the execute method allows you to execute arbitrary SQL. A migration is simply a regular Cherry grade then y'all're not limited to these functions. For example afterwards adding a column you lot could write code to gear up the value of that column for existing records (if necessary using your models).

On databases that support transactions with statements that change the schema (such as PostgreSQL or SQLite3), migrations are wrapped in a transaction. If the database does non support this (for example MySQL) and so when a migration fails the parts of information technology that succeeded volition not be rolled back. You lot will take to rollback the changes that were made past hand.

one.ii What's in a Proper noun

Migrations are stored as files in the db/migrate directory, one for each migration class. The name of the file is of the form YYYYMMDDHHMMSS_create_products.rb, that is to say a UTC timestamp identifying the migration followed by an underscore followed by the name of the migration. The proper name of the migration class (CamelCased version) should match the latter function of the file name. For example 20080906120000_create_products.rb should define class CreateProducts and 20080906120001_add_details_to_products.rb should define AddDetailsToProducts. If you practice feel the need to change the file name then yous have to update the proper name of the class inside or Rails will mutter about a missing class.

Internally Runway only uses the migration'southward number (the timestamp) to place them. Prior to Track ii.ane the migration number started at 1 and was incremented each time a migration was generated. With multiple developers information technology was easy for these to clash requiring you to rollback migrations and renumber them. With Rails 2.i+ this is largely avoided past using the creation time of the migration to identify them. Yous tin can revert to the old numbering scheme by adding the following line to config/application.rb.

config.active_record.timestamped_migrations = imitation          

The combination of timestamps and recording which migrations take been run allows Rails to handle common situations that occur with multiple developers.

For example Alice adds migrations 20080906120000 and 20080906123000 and Bob adds 20080906124500 and runs information technology. Alice finishes her changes and checks in her migrations and Bob pulls down the latest changes. When Bob runs rake db:migrate, Rails knows that it has not run Alice's two migrations so it executes the up method for each migration.

Of grade this is no substitution for communication within the team. For example, if Alice's migration removed a tabular array that Bob'due south migration assumed to exist, and then trouble would certainly strike.

1.3 Changing Migrations

Occasionally you lot will make a error when writing a migration. If you have already run the migration then y'all cannot only edit the migration and run the migration again: Rail thinks it has already run the migration and and so will do nothing when you lot run rake db:migrate. You must rollback the migration (for example with rake db:rollback), edit your migration and then run rake db:migrate to run the corrected version.

In full general editing existing migrations is not a good thought: you will exist creating actress piece of work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead, yous should write a new migration that performs the changes you require. Editing a freshly generated migration that has not all the same been committed to source command (or, more mostly, which has not been propagated beyond your development auto) is relatively harmless.

1.4 Supported Types

Active Record supports the following database column types:

  • :binary
  • :boolean
  • :appointment
  • :datetime
  • :decimal
  • :float
  • :integer
  • :primary_key
  • :cord
  • :text
  • :fourth dimension
  • :timestamp

These will exist mapped onto an appropriate underlying database type. For example, with MySQL the type :string is mapped to VARCHAR(255). Y'all can create columns of types not supported past Active Record when using the non-sexy syntax, for example

create_table :products do |t|   t.column :proper noun, 'polygon', :goose egg => false stop          

This may withal hinder portability to other databases.

2 Creating a Migration

2.i Creating a Model

The model and scaffold generators will create migrations advisable for adding a new model. This migration volition already contain instructions for creating the relevant tabular array. If you tell Rails what columns you want, then statements for adding these columns will also be created. For example, running

$ rails generate model Production name:string description:text          

will create a migration that looks like this

form CreateProducts < ActiveRecord::Migration   def change     create_table :products do |t|       t.string :proper noun       t.text :clarification        t.timestamps     end   end stop          

You can append every bit many column name/type pairs as you want. By default, the generated migration will include t.timestamps (which creates the updated_at and created_at columns that are automatically populated by Active Record).

two.2 Creating a Standalone Migration

If you are creating migrations for other purposes (for instance to add a column to an existing table) and then you lot tin can also apply the migration generator:

$ rails generate migration AddPartNumberToProducts          

This volition create an empty but accordingly named migration:

form AddPartNumberToProducts < ActiveRecord::Migration   def change   finish stop          

If the migration proper name is of the class "AddXXXToYYY" or "RemoveXXXFromYYY" and is followed by a list of column names and types and then a migration containing the appropriate add_column and remove_column statements volition be created.

$ rail generate migration AddPartNumberToProducts part_number:cord          

will generate

class AddPartNumberToProducts < ActiveRecord::Migration   def alter     add_column :products, :part_number, :string   end cease          

Similarly,

$ rails generate migration RemovePartNumberFromProducts part_number:string          

generates

class RemovePartNumberFromProducts < ActiveRecord::Migration   def upward     remove_column :products, :part_number   end    def down     add_column :products, :part_number, :cord   end end          

You are not express to one magically generated column, for example

$ rails generate migration AddDetailsToProducts part_number:cord price:decimal          

generates

class AddDetailsToProducts < ActiveRecord::Migration   def modify     add_column :products, :part_number, :cord     add_column :products, :cost, :decimal   end stop          

Every bit e'er, what has been generated for you is just a starting indicate. You tin add or remove from it as you lot see fit by editing the db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb file.

The generated migration file for destructive migrations will still be quondam-style using the up and down methods. This is considering Rails needs to know the original data types defined when you made the original changes.

3 Writing a Migration

Once you have created your migration using ane of the generators information technology'south time to go to work!

3.1 Creating a Tabular array

Migration method create_table will be one of your workhorses. A typical utilise would exist

create_table :products do |t|   t.string :name end          

which creates a products tabular array with a column chosen proper noun (and as discussed below, an implicit id column).

The object yielded to the block allows y'all to create columns on the tabular array. In that location are 2 ways of doing it. The starting time (traditional) form looks like

create_table :products do |t|   t.column :proper noun, :string, :null => false end          

The second grade, the so called "sexy" migration, drops the somewhat redundant column method. Instead, the string, integer, etc. methods create a column of that type. Subsequent parameters are the aforementioned.

create_table :products practise |t|   t.string :name, :zippo => false finish          

By default, create_table volition create a primary central called id. You can change the name of the primary fundamental with the :primary_key option (don't forget to update the corresponding model) or, if you don't desire a primary key at all (for example for a HABTM bring together table), you can laissez passer the option :id => false. If yous need to pass database specific options you can place an SQL fragment in the :options selection. For example,

create_table :products, :options => "ENGINE=BLACKHOLE" practice |t|   t.string :name, :null => false end          

will append ENGINE=BLACKHOLE to the SQL statement used to create the table (when using MySQL, the default is ENGINE=InnoDB).

3.ii Changing Tables

A shut cousin of create_table is change_table, used for irresolute existing tables. It is used in a similar fashion to create_table but the object yielded to the cake knows more than tricks. For example

change_table :products do |t|   t.remove :description, :proper name   t.string :part_number   t.index :part_number   t.rename :upccode, :upc_code end          

removes the description and proper noun columns, creates a part_number cord cavalcade and adds an index on it. Finally information technology renames the upccode cavalcade.

3.iii Special Helpers

Active Record provides some shortcuts for mutual functionality. It is for instance very common to add both the created_at and updated_at columns and and then there is a method that does exactly that:

create_table :products do |t|   t.timestamps end          

will create a new products table with those two columns (plus the id column) whereas

change_table :products do |t|   t.timestamps end          

adds those columns to an existing tabular array.

Another helper is called references (also available as belongs_to). In its simplest form information technology just adds some readability.

create_table :products do |t|   t.references :category terminate          

will create a category_id column of the appropriate blazon. Note that you pass the model name, non the column name. Active Record adds the _id for y'all. If you have polymorphic belongs_to associations then references will add both of the columns required:

create_table :products practise |t|   t.references :zipper, :polymorphic => {:default => 'Photograph'} end          

will add together an attachment_id column and a cord attachment_type column with a default value of 'Photo'.

The references helper does not actually create foreign fundamental constraints for y'all. You will demand to use execute or a plugin that adds foreign key support.

If the helpers provided by Active Record aren't enough you can use the execute method to execute arbitrary SQL.

For more details and examples of individual methods, check the API documentation, in detail the documentation for ActiveRecord::ConnectionAdapters::SchemaStatements (which provides the methods available in the up and down methods), ActiveRecord::ConnectionAdapters::TableDefinition (which provides the methods bachelor on the object yielded by create_table) and ActiveRecord::ConnectionAdapters::Table (which provides the methods available on the object yielded by change_table).

3.4 Using the change Method

The modify method removes the need to write both upward and down methods in those cases that Rail know how to revert the changes automatically. Currently, the alter method supports only these migration definitions:

  • add_column
  • add_index
  • add_timestamps
  • create_table
  • remove_timestamps
  • rename_column
  • rename_index
  • rename_table

If you're going to need to use whatsoever other methods, you'll have to write the upwards and down methods instead of using the alter method.

iii.5 Using the upward/downward Methods

The downwards method of your migration should revert the transformations done by the upwardly method. In other words, the database schema should be unchanged if you practice an up followed by a down. For example, if you create a tabular array in the up method, you should driblet it in the down method. Information technology is wise to reverse the transformations in precisely the reverse order they were fabricated in the up method. For example,

course ExampleMigration < ActiveRecord::Migration   def upward     create_table :products exercise |t|       t.references :category     terminate     #add a foreign key     execute <<-SQL       ALTER Tabular array products         Add CONSTRAINT fk_products_categories         Foreign KEY (category_id)         REFERENCES categories(id)     SQL     add_column :users, :home_page_url, :string     rename_column :users, :email, :email_address   stop    def down     rename_column :users, :email_address, :e-mail     remove_column :users, :home_page_url     execute <<-SQL       ALTER Tabular array products         DROP FOREIGN Key fk_products_categories     SQL     drop_table :products   cease cease          

Sometimes your migration will exercise something which is only patently irreversible; for example, information technology might destroy some data. In such cases, y'all tin raise ActiveRecord::IrreversibleMigration from your down method. If someone tries to revert your migration, an error message will be displayed proverb that it can't be done.

4 Running Migrations

Track provides a prepare of rake tasks to work with migrations which boil downwardly to running certain sets of migrations.

The very first migration related rake chore you will use will probably be rake db:migrate. In its most basic form information technology just runs the upward or change method for all the migrations that have not nevertheless been run. If there are no such migrations, it exits. It will run these migrations in social club based on the engagement of the migration.

Note that running the db:migrate besides invokes the db:schema:dump task, which volition update your db/schema.rb file to lucifer the construction of your database.

If you specify a target version, Active Record volition run the required migrations (up, downward or change) until it has reached the specified version. The version is the numerical prefix on the migration's filename. For case, to drift to version 20080906120000 run

$ rake db:migrate VERSION=20080906120000          

If version 20080906120000 is greater than the current version (i.e., it is migrating upwards), this volition run the up method on all migrations upwardly to and including 20080906120000, and volition not execute any later migrations. If migrating downwards, this will run the downward method on all the migrations downward to, but non including, 20080906120000.

4.one Rolling Back

A mutual chore is to rollback the last migration, for example if you made a mistake in it and wish to correct it. Rather than tracking downwards the version number associated with the previous migration y'all tin can run

This will run the down method from the latest migration. If you need to undo several migrations you can provide a STEP parameter:

$ rake db:rollback STEP=3          

will run the downward method from the final iii migrations.

The db:drift:redo chore is a shortcut for doing a rollback and then migrating support again. As with the db:rollback task, you can utilise the Footstep parameter if you need to go more than one version dorsum, for example

$ rake db:migrate:redo STEP=3          

Neither of these Rake tasks do anything you lot could non practise with db:drift. They are but more convenient, since you lot practice not need to explicitly specify the version to migrate to.

4.2 Resetting the database

The rake db:reset task will drop the database, recreate it and load the current schema into it.

This is not the same equally running all the migrations – see the section on schema.rb.

4.3 Running specific migrations

If you demand to run a specific migration up or down, the db:migrate:upward and db:migrate:downward tasks will practise that. Just specify the appropriate version and the corresponding migration will take its upwards or down method invoked, for example,

$ rake db:migrate:up VERSION=20080906120000          

will run the upwards method from the 20080906120000 migration. These tasks still check whether the migration has already run, then for instance db:migrate:upwardly VERSION=20080906120000 will do naught if Active Record believes that 20080906120000 has already been run.

iv.4 Changing the output of running migrations

By default migrations tell you exactly what they're doing and how long it took. A migration creating a table and adding an index might produce output like this

==  CreateProducts: migrating ================================================= -- create_table(:products)    -> 0.0028s ==  CreateProducts: migrated (0.0028s) ========================================          

Several methods are provided in migrations that let you to command all this:

Method Purpose
suppress_messages Takes a block equally an argument and suppresses any output generated past the block.
say Takes a bulletin statement and outputs it as is. A 2d boolean argument can be passed to specify whether to indent or not.
say_with_time Outputs text along with how long it took to run its block. If the cake returns an integer it assumes it is the number of rows afflicted.

For instance, this migration

class CreateProducts < ActiveRecord::Migration   def change     suppress_messages do       create_table :products do |t|         t.cord :name         t.text :description         t.timestamps       end     end     say "Created a table"     suppress_messages {add_index :products, :name}     say "and an index!", true     say_with_time 'Waiting for a while' do       sleep 10       250     end   end finish          

generates the following output

==  CreateProducts: migrating ================================================= -- Created a tabular array    -> and an index! -- Waiting for a while    -> ten.0013s    -> 250 rows ==  CreateProducts: migrated (ten.0054s) =======================================          

If you lot want Active Record to non output anything, then running rake db:migrate VERBOSE=false will suppress all output.

5 Using Models in Your Migrations

When creating or updating data in a migration it is often tempting to utilise one of your models. Afterward all, they exist to provide easy access to the underlying data. This tin can exist done, but some caution should be observed.

For example, problems occur when the model uses database columns which are (ane) not currently in the database and (2) will be created past this or a subsequent migration.

Consider this case, where Alice and Bob are working on the same lawmaking base which contains a Production model:

Bob goes on holiday.

Alice creates a migration for the products table which adds a new cavalcade and initializes it. She also adds a validation to the Product model for the new column.

# db/migrate/20100513121110_add_flag_to_product.rb  class AddFlagToProduct < ActiveRecord::Migration   def modify     add_column :products, :flag, :boolean     Product.all.each do |product|       product.update_attributes!(:flag => 'faux')     end   stop end          
# app/model/product.rb  form Product < ActiveRecord::Base   validates :flag, :presence => true terminate          

Alice adds a second migration which adds and initializes some other column to the products table and also adds a validation to the Product model for the new column.

# db/drift/20100515121110_add_fuzz_to_product.rb  form AddFuzzToProduct < ActiveRecord::Migration   def change     add_column :products, :fuzz, :string     Product.all.each do |product|       product.update_attributes! :fuzz => 'fuzzy'     terminate   end stop          
# app/model/production.rb  class Production < ActiveRecord::Base   validates :flag, :fuzz, :presence => truthful end          

Both migrations work for Alice.

Bob comes dorsum from vacation and:

  1. Updates the source – which contains both migrations and the latests version of the Product model.
  2. Runs outstanding migrations with rake db:migrate, which includes the one that updates the Product model.

The migration crashes considering when the model attempts to save, it tries to validate the second added column, which is non in the database when the first migration runs:

rake aborted! An fault has occurred, this and all afterwards migrations canceled:  undefined method `fuzz' for #<Product:0x000001049b14a0>          

A prepare for this is to create a local model within the migration. This keeps rails from running the validations, and so that the migrations run to completion.

When using a faux model, it's a expert idea to phone call Production.reset_column_information to refresh the ActiveRecord cache for the Product model prior to updating data in the database.

If Alice had washed this instead, there would have been no problem:

# db/migrate/20100513121110_add_flag_to_product.rb  class AddFlagToProduct < ActiveRecord::Migration   course Production < ActiveRecord::Base   end    def modify     add_column :products, :flag, :integer     Product.reset_column_information     Product.all.each do |product|       product.update_attributes!(:flag => faux)     end   end end          
# db/migrate/20100515121110_add_fuzz_to_product.rb  class AddFuzzToProduct < ActiveRecord::Migration   class Production < ActiveRecord::Base   finish    def change     add_column :products, :fuzz, :string     Product.reset_column_information     Product.all.each do |product|       product.update_attributes!(:fuzz => 'fuzzy')     end   finish end          

6 Schema Dumping and You

vi.one What are Schema Files for?

Migrations, mighty as they may be, are not the authoritative source for your database schema. That role falls to either db/schema.rb or an SQL file which Active Record generates by examining the database. They are not designed to be edited, they just correspond the current state of the database.

There is no need (and it is mistake decumbent) to deploy a new case of an app by replaying the unabridged migration history. It is much simpler and faster to merely load into the database a description of the current schema.

For instance, this is how the test database is created: the current development database is dumped (either to db/schema.rb or db/structure.sql) and then loaded into the exam database.

Schema files are also useful if you lot want a quick expect at what attributes an Agile Tape object has. This information is non in the model'southward code and is frequently spread beyond several migrations, just the information is nicely summed upward in the schema file. The annotate_models gem automatically adds and updates comments at the top of each model summarizing the schema if yous desire that functionality.

6.two Types of Schema Dumps

At that place are ii ways to dump the schema. This is set in config/application.rb by the config.active_record.schema_format setting, which may be either :sql or :ruby.

If :ruby is selected and so the schema is stored in db/schema.rb. If you lot look at this file you'll detect that it looks an awful lot like i very big migration:

ActiveRecord::Schema.ascertain(:version => 20080906171750) do   create_table "authors", :strength => true do |t|     t.string   "proper name"     t.datetime "created_at"     t.datetime "updated_at"   end    create_table "products", :force => true do |t|     t.cord   "name"     t.text "description"     t.datetime "created_at"     t.datetime "updated_at"     t.string "part_number"   finish end          

In many ways this is exactly what it is. This file is created past inspecting the database and expressing its structure using create_table, add_index, and then on. Considering this is database-independent, it could be loaded into any database that Active Tape supports. This could exist very useful if you were to distribute an awarding that is able to run against multiple databases.

There is however a merchandise-off: db/schema.rb cannot express database specific items such every bit foreign primal constraints, triggers, or stored procedures. While in a migration you can execute custom SQL statements, the schema dumper cannot reconstitute those statements from the database. If y'all are using features like this, and so you should prepare the schema format to :sql.

Instead of using Active Record'south schema dumper, the database's structure will exist dumped using a tool specific to the database (via the db:construction:dump Rake task) into db/structure.sql. For case, for the PostgreSQL RDBMS, the pg_dump utility is used. For MySQL, this file will contain the output of Testify CREATE TABLE for the various tables. Loading these schemas is simply a question of executing the SQL statements they contain. By definition, this will create a perfect copy of the database's structure. Using the :sql schema format volition, however, prevent loading the schema into a RDBMS other than the one used to create information technology.

6.3 Schema Dumps and Source Command

Because schema dumps are the authoritative source for your database schema, it is strongly recommended that you check them into source command.

vii Agile Record and Referential Integrity

The Agile Record way claims that intelligence belongs in your models, not in the database. Every bit such, features such as triggers or strange primal constraints, which push some of that intelligence back into the database, are not heavily used.

Validations such as validates :foreign_key, :uniqueness => truthful are one style in which models tin can enforce data integrity. The :dependent option on associations allows models to automatically destroy child objects when the parent is destroyed. Like annihilation which operates at the application level, these cannot guarantee referential integrity and then some people augment them with foreign central constraints in the database.

Although Agile Record does not provide whatsoever tools for working directly with such features, the execute method can be used to execute capricious SQL. You lot could too utilize some plugin like greenhorn which add strange fundamental support to Active Record (including support for dumping foreign keys in db/schema.rb).

Feedback

Y'all're encouraged to help improve the quality of this guide.

If y'all see any typos or factual errors you are confident to patch, please clone docrails and push the change yourself. That branch of Rails has public write access. Commits are still reviewed, just that happens after you've submitted your contribution. docrails is cross-merged with chief periodically.

You lot may also notice incomplete content, or stuff that is not up to date. Delight do add whatsoever missing documentation for master. Check the Reddish on Rails Guides Guidelines for manner and conventions.

If for any reason y'all spot something to ready merely cannot patch information technology yourself, please open up an issue.

And last only not to the lowest degree, whatever kind of discussion regarding Ruby on Rails documentation is very welcome in the rubyonrails-docs mailing list.

hillfithaly.blogspot.com

Source: https://guides.rubyonrails.org/v3.2.9/migrations.html

0 Response to "Ruby on Rails Backup Database and Run Migration Again"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel