When I start coding a Ruby on Rails project, I find myself modifying the migration files over and over. I know this is not the way they were intended to use, but to avoid upfront design, I only ad fields when I need them. If I respected the way migrations were intended I would end up with hundred of migrations the first day and I would waste half my day just creating migrations.
After a project is deployed or a second developer is working on it, I revert to the way migrations are intended and I create a new one every time there’s a change I need in the database.
As migrations are intended to run only once, if you modify them, they won’t get run; and if you force them to run them, they’ll fail, because the database already contains such a table. So I’ve found myself doing this quite often:
rake db:drop && rake db:create && rake db:migrate && rake db:seed && rake db:data
db:data is a task I created to generate some sample data. Good known data that I can use to test the site locally. I’m using Factory Girl to create it, which I also use for the tests so I can re-use as much data creating logic as possible. It’s very good to get to a known state of the project you are developing and to get other developers started right away. I really recommend everyone doing it.
The problem is that I also need to reset my test data, so I end up having this other command and it gets horrible:
RAILS_ENV=test rake db:drop && RAILS_ENV=test rake db:create && RAILS_ENV=test rake db:migrate && RAILS_ENV=test rake db:seed
Note: no db:data this time.
I’ve got tired of re-writing these commands or trying to find them in my bash history, so I decided to write a Ruby task that will do it for me and here it is in case you want to use it too:
namespace :db do desc "Crush and burn the database" task :hard_reset => :environment do File.delete("db/schema.rb") Rake::Task["db:drop"].execute Rake::Task["db:create"].execute Rake::Task["db:migrate"].execute Rake::Task["db:seed"].execute if !Rails.env.test? Rake::Task["db:data"].execute end end desc "Generate sample data for developing" task :data => :environment do # Create the sample data in here end end
Update: To delete all records without resetting the whole database, check my post Deleting all records in a Rails project.