Rails has a great feature called migrations which allow the developer to have control over the database schema by using ruby code and avoiding use the conventional SQL language. But, more important is that the developer can apply certain changes to move a database from one state to another, add-remove columns, indexes, tables etc. By using migrations you can get different versions of your database structure.
How it works? Migrations are files found in the db/migrate directory and have a sequence number in the filename.
For example, each time you want to add a migration you can generate it with:
./script/generate migration CreateCompanies exists db/migrate create db/migrate/001_create_companies.rb Loaded suite ./script/generate Started Finished in 0.002254 seconds. 0 tests, 0 assertions, 0 failures, 0 errors
If you see the file, this was generated for you:
class CreateCompanies < ActiveRecord::Migration def self.up end def self.down end end
and now you can modify it to create a table, the syntax is the folowing:
class CreateCompanies < ActiveRecord::Migration def self.up create_table :companies do |t| t.string :name t.text :description t.datetime :created_on t.timestamps end end def self.down drop_table :companies end end
I think the code is explained implicity. It’s similar to an sql creation, but this time you have to add the datatype first and then the column name.
Possible Column types:
:string, :text, :integer, :float, :datetime, :timestamp, :time, :date, :binary, :boolean
:limit: Maximum long characters in the column (for types :string, :text, :binary or :integer)
:default: Specify the default value of the column.
:null: Enable or disable the value NULL in a column.
To get this table created, just you have to run the command: rake db:migrate and the companies table will be created.
Imagine you want to create another table users, generate it with:
./script/generate migration CreateUsers exists db/migrate create db/migrate/002_create_users.rb Loaded suite ./script/generate Started Finished in 0.002254 seconds. 0 tests, 0 assertions, 0 failures, 0 errors Modify the file 002_create_users.rb class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.string :login t.string :email t.string :password, :limit => 20 t.datetime :created_at t.datetime :updated_at t.integer :status t.datetime :last_login t.timestamps end end def self.down drop_table :users end end
and if you run rake again db:migrate table users will be created in your database. You are probably wondering how rails knows next migration should be named 002 and when running rake db:migrate which migration has to be executed.
Whenever doing these operations rails checks in your database a table called schema_info, which has the latest version of your database schema. So, that way rails knows which migration number to apply or generate.
Try to run again rake db:migrate and you will receive an error message
Mysql::Error: Table ‘users’ already exists:
telling you that table users already exists. This is because this migration was already executed and in your schema_info table the version is 2 (the same as the number of your migration). Now you can realize what the pattern is. Also you can execute an specific migration by running:
rake db:migrate version= version_number
version_number is the version you want to be executed.
When developing your rails application you will see that migrations are very useful because you are database-independent, can change to one version or another and undo changes easily.
Thanks for your visit to the blog. You can follow me on Twitter: Follow @ronnyml