Show:

rake db:schema:load vs rake db:migrate

March 24, 2016 Programming

Sooner or later every new Ruby developer needs to understand differences between rake db:schema:load and rake db:migrate. Basically, these simple definition tells us everything we need to know:

  • rake db:migrate runs migrations that have not run yet
  • rake db:schema:load loads the schema.db file into database.

but the real question is when to use one or the other.

Advice: when you are adding a new migration to an existing app then you need to run rake db:migrate, but when you join to existing application (especially some old application), or when you drop your applications database and you need to create it again, always run rake db:schema:load to load schema.

Example

I am working on application which use globalize gem for ActiveRecord model/data translations. Globalize work this way:

  • first specify attributes which need to be translatable
    class Post < ActiveRecord::Base
    translates :title, :text
    end
    
  • then create translation tables
    class CreatePosts < ActiveRecord::Migration
    def up
    create_table :posts do |t|
    t.timestamps
    end
    Post.create_translation_table! title: :string, text: :text
    end
    def down
    drop_table :posts
    Post.drop_translation_table!
    end
    end
    

    Note that the ActiveRecord model Post must already exist and have listed attributes for translations.

  • and run rake db:migrate.
    Problem comes when you change your mind and decide to leave title to be untranslatable.
  • remove title from post translations table
    class RemoveTitleFromPostTranslations < ActiveRecord::Migration
    def up
    remove_column :post_translations, :title, :string
    end
    
    def down
    Entry.add_translation_fields! title: :string
    end
    end
    
  • add title to posts table
    class AddTitleToPosts < ActiveRecord::Migration
    def change
    add_column :posts, :title, :string
    end
    end
    
  • remove title attribute from model translations
    class Post < ActiveRecord::Base
    translates :text
    end
    
  • and run rake db:migrate.

Everything looking good, so where is the problem?

Here it is! If you decide to delete your database and create it again you need to use:

  • rake db:drop
  • rake db:create
  • rake db:schema:load

Because, if you try to use rake db:migrate instead of rake db:schema:load you will get BIG ERROR!, because for your first migration “create_posts” it is necessary that you have defined translatable attributes :title and :text in Post model, but you removed :title from Post model translations.

So just follow advice above, and good luck.