Upgrading to Rails 5: Solving NoEnvironmentInSchemaError

I’ve been upgrading Simplero to Rails 5 over the past few days. Since I have a running application with customers all over the world, I’m going to do that on a branch and test it thoroughly until I’m prettty certain everything works.

 

So while that’s going on, I find myself switching between my Rails 4.2 branch and the Rails 5 branche.

 

And this would cause my automated builds on Jenkins to start failing with this error:

 

rails aborted!
ActiveRecord::NoEnvironmentInSchemaError: 

Environment data not found in the schema. To resolve this issue, run: 

	bin/rails db:environment:set RAILS_ENV=test

It took me quite a while to figure out what needed to happen, since this is not documented very well in neither the code nor elsewhere that I found.

This feature depends on a magic table existing in your database, named “ar_internal_metadata”. This table has one row, which contains the key ‘environment’ and the value ‘test’ in this case. The goal is to prevent you from accidentally dropping your production database, thinking it was the test database.

The problem occurred, because I was switching back to the Rails 4.2 branch, and while there, Rails would save the db/schema.rb file, which would now include the ar_internal_metadata table, but with an incorrect definition. Next time Jenkins ran my Rails 5 tests, it would find that table, and thus not create it, but it wouldn’t work, because the primary key was created as an int(11) and not a varchar(255).

The solution was to write a small line of code that just removes that table from the test database, if it exists, before starting the test suite. The line looks like this:

mysql -e 'DROP TABLE ar_internal_metadata;' simplero_test || true

 The last || true part is so Jenkins doesn’t fail if the table doesn’t exist.

So if you run into something similar, now you know what’s going on.