Is is correct to assume that migrations in ruby on rails are simply updates to any database. And that the rake db:migrate script only serves to actualize these changes?
Yes.
Migrations are a convenient way for you to alter your database in a
structured and organized manner. You could edit fragments of SQL by
hand but you would then be responsible for telling other developers
that they need to go and run them. You’d also have to keep track of
which changes need to be run against the production machines next time
you deploy.
Active Record tracks which migrations have already been run so all you
have to do is update your source and run rake db:migrate. Active
Record will work out which migrations should be run. It will also
update your db/schema.rb file to match the structure of your database.
Migrations also allow you to describe these transformations using
Ruby. The great thing about this is that (like most of Active Record’s
functionality) it is database independent: you don’t need to worry
about the precise syntax of CREATE TABLE any more than you worry about
variations on SELECT * (you can drop down to raw SQL for database
specific features). For example you could use SQLite3 in development,
but MySQL in production.
Source: Ruby on Rails Guides: Migrations
Related
I'm learning Ruby on Rails and it talk about how Migration changes the state of the database by using the command bundle exec rake db:migrate, but what exactly does that mean?
Migrations are a way of defining the schema of your database. Rails provides an API for adding/dropping/modifying database columns and tables using Ruby code. These files are knows as migrations. Here is a link to the documentation: http://edgeguides.rubyonrails.org/active_record_migrations.html,
but migrations are not a concept unique to Rails. For example, Django also uses migrations to manage the state of the database. The short answer is that migrations are a code-based way to manage the structure, or schema of your database.
It executes all the migrations that you created/generated via rails generate migration X.
Basically migrations are scripts that deal directly with the database (creating tables, fields, indexes). Hope that helps! :)
So after alot of reading i found out that i dont need to plan my database ahead. I just start working on the application and do migrations on every change.
So for example if I decide to add something I add it via migration. Then on another migration I delete it for some reason. And in the end I decide to get it back. After a short time there will be a mess of migrations.
How do I keep track of them? Wouldnt be easier to think of the database structure in the first place?
Rails way is to do everything via migrations. As per your scenario it would be like:
migration1 #add column A
migration2 #remove column A
migration3 #add column A again
It seems like there are lots of migrations, but in practical scenario it will keep your database changes clean. Because at any given time when you do:
rake db:migrate
Rails will run only the pending migrations.
And at any given time you will see the db/schema.rb file with all the migrates and latest migration number as the version.
Having said that, if you want to revert a migration there are commands like rollback commands. Read more about migrations here.
You can see your database structure inside db/schema.rb which will show you all the tables, columns and indexes currently in your app.
Not as helpful if you're constantly changing a column, but you can also run rake db:migrate:status which will output a list of all migrations, and tell you whether they've been run or not.
I used to think the db/schema.rb in a Rails project stored the database schema, so that ActiveRecord can know what table/column it has.
But earlier I surprisingly noticed that my project runs normally after I delete db/schema.rb!
So, since the Rails can work without it, what does schema.rb really do?
The schema.rb serves mainly two purposes:
It documents the final current state of the database schema. Often, especially when you have more than a couple of migrations, it's hard to deduce the schema just from the migrations alone. With a present schema.rb, you can just have a look there. ActiveRecord itself will indeed not use it. It will introspect the database during runtime as this is much safer than to expect users to keep the schema.rb up-to-date. However to avoid confusion of your developers, you should always maintain a file that is up-to-date with your migrations.
It is used by the tests to populate the database schema. As such a rake db:schema:dump is often run as part of the rake test:prepare run. The purpose is that the schema of the test database exactly matches the current development database.
Rails Documentation / 6.1 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 represent the current state
of the database.
There is no need (and it is error prone) to deploy a new instance of
an app by replaying the entire migration history. It is much simpler
and faster to just load into the database a description of the current
schema.
For example, 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 test database.
Schema files are also useful if you want a quick look at what
attributes an Active Record object has. This information is not in the
model's code and is frequently spread across several migrations, but
the information is nicely summed up in the schema file. The
annotate_models gem automatically adds and updates comments at the top
of each model summarizing the schema if you desire that functionality.
Rails documents have you covered.
I'm switching to RoR from ASP.NET MVC. Yeah, migrations are cool, but I do not need to use different databases in my web applications. Postgresql will do just fine.
So is it okay if I use PGAdmin to create and administer my databases and schema and avoid all these fancy migrate, rake etc?
Update
Thanks everyone! Now I better understand what migrations are, and why I should use them.
I don't think that's what migration means.
Migrations in rails (and in other frameworks) is a method by which you can use to update your database schema when there are multiple versions of the same database running
For example, you may have two databases, one running on your production server, and another running locally for development. After a few days of coding, your local development database may looks a bit different. With migrations, you can simply push your code to the production server and then run the migrations to automatically update your production database so it is up-to-date with the one you use locally for development.
So, to answer your question, Yes it is OK but you might not get a few of the migrations niceties when the time comes that you'll have to maintain multiple versions of your database.
Have to agree with charkit but one (rather two) important note why you should use migrations: Migrations don't make up the model definitions. They are stored seperately in a file schema.rb. This defines the rows and tables of your database. When looking into the file, you find these lines:
This file is auto-generated from the current state of the database. Instead of editing this file, please use the migrations feature of Active Record to incrementally modify your database, and then regenerate this schema definition.
The second reason is for testing: you can easily set up a test database to run all your tests against without the need to touch the "real" database. I know when developing, this is not a big problem but this will get more important after some time.
So, yes, it is possible to use PGAdmin to create all your database related stuff but you should not forget to always keep the schema file up to date and come up with a solution for testing.
With migrations you're able to develop your database schema in Ruby and this is usually database indpendent.
In short, spend the 20 minutes or so to really get migrations and the value they add. Then determine whether or not you want to ditch them. Strangely for me I learned Rails before I started my first MVC project; one of the things I missed most was migrations.
From a technical standpoint you should be fine without them.
So what's the best way to create new tables in a Sqlite database in Rails 2. I have created the database using rake db:migrate command. So should I write individual sql scripts to create a database or use rake somehow. I don't need scaffolding.
Basically use migrations.
Some useful help on how to use migrations is available at http://wiki.rubyonrails.org/rails/pages/understandingmigrations and http://wiki.rubyonrails.org/rails/pages/UsingMigrations. A good cheatsheet that I use is also available at http://dizzy.co.uk/ruby_on_rails/cheatsheets/rails-migrations.
Basically migrations use ruby code to create your database tables for you. It is far easier (in my opinion at least) to use nice ruby code to do this rather than SQL DDL - it also does various things automatically for you (like adding id fields to all your tables as rails requires). You can then use rake tasks to actually apply the migrations to your database. The other major advantage that migrations give you is that they are reverseable - so your database is versioned and you can easily jump from one version to another.
Try to avoid writing CREATE/ALTER table scripts and use ActiveRecord migrations instead. A few reasons spring to mind:
Portability: it's much easier to let
AR deal with cross-platform flavour
differences
Change control: your
migrations can manage changes in
both directions with the VERSION=
option, something that's not easy to
do with SQL
It's the Rails way:
follow the Rails conventions unless
you have a compelling reason not to
do so
Simplicity: you don't have to worry about id and timestamp columns when you use migrations, which saves you having to remember them if you work in SQL
If you are not using scaffolding then you should use script/generate migration to create a migration file for each table. There is no need to use sql scripts. After creating some migrations you can apply them to your database using rake db:migrate.