Matt Connolly's Blog

my brain dumps here…

Monthly Archives: July 2011

Using rvm on OpenIndiana

OpenIndiana is a fork of Sun’s OpenSolaris before it was killed by Oracle. There’s quite a few commands in there that are different from linux, and there’s been a bit of discussion on the openindiana mailing list about whether commands should be more linux like or not.

In any case, there’s the built in commands in /usr/bin and the linux-like versions in /usr/gnu/bin. This is what you need in your path to use the linux versions, which I have, but I have it at the end of my path.

Unfortunately that’s no good for rvm. Well at least for the rvm upgrading part.

You can put /usr/gnu/bin at the beginning of your PATH. Or if you don’t want to do that, you can:

$ # installing:
$ PATH=/usr/gnu/bin:$PATH bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
$ # upgrading
$ PATH=/usr/gnu/bin rvm get latest

A Ruby gem to backup and migrate data from a Rails app

Ever wanted to quickly duplicate your database in a rails app so you can do some development work on real data, but not risk breaking it?

Background:

Rails has some very good strategies for managing your schema with rake tasks such as db:migrate, db:schema:load, etc. Switching between production and development environments lets you use different databases.

Great, but how do you get the data from one environment to another?

With MySQL you can duplicate a database (easy with phpMyAdmin), and with Sqlite3 you can simply copy the database.db file.

But what if I want to go from MySQL to Sqlite3 just for working??

There are some database differences, and there’s a rake task that’s already managing the database structure. I need something to move the data as well.

In my particular case, I’m using redmine as an issue tracker, hacking on it, and also evaluating the Chiliproject fork. So I’d like to be able to move all my data: schema, data and files easily from one to another.

The Rails-Backup-Migrate Gem

So, I put together a gem to do this. It’s inspired by Tobias Lütke’s backup.rake file he posted a good 5 years ago: http://blog.leetsoft.com/2006/5/29/easy-migration-between-databases

It appears to be for an early version of rails. It also had some issues with tables belonging to “many-to-many” relationships, and was also slow because it instantiated every single ActiveRecord object as it went.

I’ve sped the process up by skipping the ActiveRecord object steps, and updated the table definitions for rails 2.3 (redmine runs on this) and it appears to be working for rails 3.0 as well.

This gem provides the following rake tasks to a rails app:

rake site:backup[backup_file]                          # Backup everything: schema, database to yml, and all files in 'files' directory.
rake site:backup:db[backup_file]                       # Dump schema and entire db in YML files to a backup file.
rake site:backup:files[backup_file]                    # Archive all files in the `files` directory into a backup file.
rake site:backup:schema[backup_file]                   # Dump schema to a backup file.
rake site:restore[backup_file]                         # Erase and reload db schema and data from backup files, and restore all files in the 'files' directory.
rake site:restore:db[backup_file]                      # Erase and reload entire db schema and data from backup file.
rake site:restore:files[backup_file]                   # Restore all files in the 'files' directory.
rake site:restore:schema[backup_file]                  # Erase and reload db schema from backup file.

The default backup_file is "site-backup.tgz" and is relative to rails app root directory.

Installing:

Installing manually:

$ gem install rails-backup-migrate

Installing with Bundler:

Add the following to your Gemfile:

gem rails-backup-migrate

And then

$ bundle install

Using rails-backup-migrate:

To use the gem in your rails app, simply add the following line to the end of your Rakefile:

require 'rails-backup-migrate'

Which will load the above tasks into your rails app’s task list. If you’re using bundler

$ # backup everything into the default file 'site-backup.tgz'
$ rake site:backup
$ # now, restore into another instance (eg: clone/checkout another copy of your project)
$ cd /path/to/another/instance/of/my/rails/app
$ rake site:restore[/path/to/original/instance/of/my/rails/app/site-backup.tgz]

Done.

The source code is available on github: https://github.com/mattconnolly/rails-backup-migrate

This is the first gem I’ve made and published, and I hope it makes life a little bit easier for someone!