You should always commit Gemfile.lock and schema.rb

One of common mistakes I see with new (and some experienced) Ruby on Rails programmers is that they do not commit Gemfile.lock and schema.rb very often to source control version such as Git or SVN. I personally think that it is generally bad practices and we should commit those two files into Git/SVN. Here is my explanation.

Gemfile.lock

After you add new gem to Gemfile and run bundle install, your Gemfile.lock will be updated. If you have ever opened this file, you would notice that it contains a very specific version of every gem in your project.

So why do we need to commit this file if we can easily generate it using bundle install command? The problem is your project could perhaps run smoothly in your local computer with those versions of gems, but it just won't work correctly with different versions of gems in deployment server, for example. One famous example I have seen recently is devise gem. For version >= 3.1, devise change the way secure tokens are generated when resetting password. So if devise version is 3.0 in your local but 3.1 on your server, resetting password function will not work on your server.

So why commiting Gemfile.lock would help? When you run bundle install, bundler will first check Gemfile.lock and it will try to install the gems with correct version defined in this Gemfile.lock, it only installs other version if and only if it can not found in Gemfile.lock. That's why, if you app in running properly with current Gemfile.lock in your local, remember to commit this file to Git/SVN after every changes to it.

schema.rb

Yeah, we all know that we can quickly create a full database schema in Ruby on Rails thanks to migration. However, remember that a migration file is written in Ruby and there could be error (syntax or runtime) related to these migrations. In my experience, I have worked with many different existing projects with broken migration files and we just simply can not create full database schema with rake db:migrate. In that case, schama.rb is our saviour. This file contains the latest schema you have when developing your app and it would be automatically updated if your db schema is changed. In addition, if you look closely at this file, you will notice the following sentence in comment section

# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended to check this file into your version control system.

Yeah, notice the last sentence: It's strongly recommended to check this file into your version control system.. That's right, I don't see any reason for not committing this file to Git/SVN.