One of the main things that Rails did that made it stand out from other similar frameworks, all the way back in 2005, was that it read your database schema (which tables there were and which fields those tables had) as the application started up and used them to decide which attributes should appear on your models.
Other frameworks had big mapping files (name in the Customer model maps to name in the customers table) that you had to tediously write out by hand, or pay money to buy a tool that would do it for you (and then edit it by hand).
Rails was revolutionary.
All this is done at run-time, as the app begins.
But there’s also, in your app’s db folder, a file called schema.rb. This looks like a ruby-fied version of your database schema.
What is it and what is it for?
Well, if you want to make a change to your Rails app’s database, you use migrations. These are a series of files, in the db/migrate folder, that have long version numbers (actually time-stamps) attached to them. For example 20131219115840_add_report_download_flag_to_participants.rb is from one of my projects.
When you run the
rake db:migrate command, it looks in the db/migrate folder, pulls out all the files in order (which as they are time-stamps means starting with the oldest and moving on to the newest) and checks to see if the migration has already been run. It uses a table called “schema_migrations” for this – if there is an entry of “20131219115840” in there it knows that the migration file above has already been run, if there isn’t it knows that it needs to run it.
When it runs the migration it makes whatever changes to the database (in this case
add_column :participants, :reports_downloaded_on, :date), sticks an entry into schema_migrations so the same migration isn’t run twice, and then updates db/schema.rb.
You see, while running all your migrations in order on a blank database should get you a perfect copy of your database structure, it doesn’t always work out that way. Databases are very strict and often refuse to do things if they’re not comfortable with it. And on a big app, running each migration in turn can take a very long time.
But schema.rb is a representation of the current database structure, all in one go. It’s really useful as a reference (did I call the report field name or title? just look it up in schema.rb) but also useful when testing – Rails just uses it to make an exact copy of your development database in one command – no trawling through several hundred migrations when you just want to run a test.