Rake DB Commands

**Rake** is a utility built into **Ruby and Rails**, which provides an efficient way for managing database changes. ==You can easily migrate database changes to servers by only using a command line!==

You might be asking yourself during your application development:
* *What happens* when using **rake database commands**? 
* *When* should I use them? 

Let’s take a look at how we can use these commands to change our database while developing an application!
## Creating
`$ rake db:create`
When you **create** your Rails application for the first time, it will not have a database yet. In order for it to start, you will need to make sure the database is up and running.

Just like it's recommended to use [different gems](https://kolosek.com/rails-bundle-install-and-gemfile/) for each environment, you should also create three databases, each for **development**, **testing**, and **production** environment. You can configure them in your `config/database.yml` file.

```
default: &default
  adapter: postgresql
  encoding: unicode
  username: username
  password: password
  host: localhost
  port: 5432

development:
  <<: *default
  database: story_dev

test:
  <<: *default
  database: story_test

production:
  <<: *default
  database: story
```
## Migrating
`rake db:migrate`
**Migrations** setup the tables in the database. When you run the migration command, it will look in `db/migrate/` for any ruby files and execute them starting with the oldest. There is a **timestamp** at the beginning of each migration filename.
> *Every time you migrate a database or make any change to it such as adding a row or a column, adding a table or changing the data type, you have to run this command for the changes to reflect in your database. [List of Database Rake Tasks in a Rails Application](https://rails.devcamp.com/learn-ruby-on-rails-from-scratch/building-your-first-rails-application/list-of-database-rake-tasks-in-a-rails-application)*
> 
Migrations are created when you run commands like [rails generate scaffold](https://kolosek.com/rails-scaffold/), `rails generate model`, or `rails generate migration`. 

Here is an example how you can use `rake db:migrate` when [uploading images](https://kolosek.com/carrierwave-upload-multiple-images/). **Be sure to not have data creation in the migration files!**
## Initializing
`rake db:schema:load`
Unlike `rake db:migrate` that runs migrations that have not run yet, `rake db:schema:load` loads the schema that is already generated in `db/schema.rb` into the database. 

Always use this command when:
* You run the application for the **first time**. 
* When you **drop the database** and you need to create it again.

*Beware*! If you run `rake db:schema:load` on a production server, you'll end up deleting all your production data.
## Seeding
`rake db:seed`
We always have default data that we want to have in our application for testing purposes. The **seed command** exists to automate this process. 

*Example*: Create an admin user and  store its data in the `db/seed.rb` file. When you run `rake db:seed` it will load all the admin data into your application.

```
Admin.create!(email: 'admin@kolosek.com', 
              password: 'password', 
              password_confirmation: 'password')
```
Rails seeding is generally for **development** and/or **staging** environments, there are only a few uses in production. ==You don't want your production application to seed dummy users!==
## Rolling Back
`rake db:rollback`
Did you create a migration without wanting it or you simply changed your mind about it? *Fear not!* When you run this command, it will look at the last migration created and undo it!

*Example*: Let’s start off by creating a **new migration** with `:role` as an integer and **run the migration**. Then we decided to make it a string instead. So, we will edit the newly created migration and run it again, but nothing happens and your [tests and factories](https://kolosek.com/factory-girl-associations/) will fail.

```
class CreateRoles < ActiveRecord::Migration
  def change
    create_table :roles do |t|
      t.integer :role # we will change this to t.string :role
      t.references :user
      t.timestamps
    end
  end
end
```
**Why isn’t this working?**
Only the last created migration is run with `rake db:migrate` command. This means that no changes will be made by editing an already existing migration. To make this work, you will need to run `rake db:rollback` instead. This will tell Rails to do two things:
1. Undo the last changes you just made to the database.
2. Update the migration timestamp.
## Dropping
`rake db:drop`
Sometimes we want to delete all of the data and tables and start from fresh. That's what `rake db:drop` is for. ==If you want to keep the data you have, be sure to back it up before running this command.==

Dropping the database will also remove any **schema conflicts** or **bad data**. Once the database is dropped, you'll want to start the process over again by re-creating the database, running migrations, and seeding the data. Be sure that your [RSpec tests](https://kolosek.com/rails-rspec-setup/) are passing after remaking your database!

**Make sure you don't have connections to the database or it won't drop.**
## Resetting
`rake db:reset`
You might sometimes need to drop the local database and start fresh with data loaded from `db/seeds.rb`. This is a useful command when you are still figuring out your schema, and often need to add fields to existing models.

Once the reset command is used it will do the following:
1. Drop the database: `rake db:drop`
2. Load the schema: `rake db:schema:load` 
3. Seed the data: `rake db:seed`

**Why db:schema:load and not db:migrate?**
`rake db:schema:load` is much faster than `rake db:migrate`,  because it loads the schema that we’ve already generated from `db/schema.rb` instead of going through all the migrations again.

Hope this helped you to understand the main difference between rake database commands!

Originally published on [Kolosek Blog](https://kolosek.com/rake-db-commands/).