Wednesday, December 16, 2009

Dealing with "rake aborted! uninitialized constant MysqlCompat::MysqlRes"

This post is relevant for those running Ruby on Rails and MySQL on Leopard or Snow Leopard using the default components pre-installed in OS.  This will probably be relevant to those who have a Hive Logic roll your own from source install also.    This post might even be useful to those daring enough to do their RoR work on Linux, go Penguin Heads!

Ok, I am creating this post for those that have the misfortune of running into this error as I have.  I am not a rails noob, but I am far from a jedi, so when I run into problems I usually turn to web forums and blogs for solutions.  The only problem is there is often lots of solutions to the same problem with very little explanation as to why the solution works or a way to derive at the conclusion that the offered suggestion is in fact a solution.

That is my attempt to avoid that here.  If you are getting the dreaded "rake aborted! uninitialized constant MysqlCompat::MysqlRes" when trying to run a rake db:migrate command on your rails project their is a reason.  The reason is not Rails, and not MySQL but the mysql gem you have installed into Rails.   Basically you have installed the mysql gem incorrectly.   Luckily there is a simple trick to determine the correct method to install your mysql gem.

Since the MySQL database you installed on your OSX of some feline distinction is not a universal binary it is architecture specific.  Thus the mysql gem must also be compiled by the gcc compiler to match the same architecture.   So you have to determine the correct command and architecture to use to install the mysql gem.  I will lay out the simplest solution that I know of to correctly determine the command for yourself.

1. Open a terminal window,  btw if you need a tutorial on how to do this welcome to the unix world and don't feel bad we all have to start somewhere ;)

2. Navigate to some benign place like your desktop for example:

cd ~/Desktop/

3.  Create a simple Rails demo project with the specification for a MySQL database with the command:

rails demo --database mysql

4.  Now you need to navigate to the config folder of your project by running the command:

cd demo/config/

5. Once in the config directory running the ls command should return results like below :

Machinename:config username$ ls
boot.rb environment.rb initializers routes.rb
database.yml environments locales

6.  Use your favorite text editor to view the contents of the database.yml file, my favorite is Textmate but for convention I will us the command for vi since most folks have vi even if they don't have Textmate.

vi database.yml

7. ***IMPORTANT***  Before running any of the below commands you need to clean out any mysql gems you have already installed using the command in a terminal window after closing vi or the text editor you use to view the database.yml file

gem uninstall mysql

if given options for multiple mysql gems REMOVE THEM ALL.

8.  Inside the database.yml file you should see something similar to the text below:

Install the MySQL driver:
#   gem install mysql
# On Mac OS X:
#   sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
# On Mac OS X Leopard:
#   sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
#       This sets the ARCHFLAGS environment variable to your native architecture
# On Windows:
#   gem install mysql
#       Choose the win32 build.
#       Install MySQL and put its /bin directory on your path.

9. Notice the command for Leopard, this is **ALMOST** the command I needed to use to install the mysql gem into rails.  The reason I say almost is there was one minor change that I needed to make. You have to set the correct architecture type in the ARCHFLAGS specification.  If you are like me and Santa hasn't brought you a new powerbook in the past few years then it maybe "- arch ppc".  If you have been good then Santa may have you on the "-arch i386" arch type and if you have been really nice you may get to use "-arch x86_64" so below are the different commands for the different feline distros, but remember to clear out any already installed mysql gems first (see step 7 above).

Prior to Leopard:
sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql

Leopard on a PPC machine:
sudo env ARCHFLAGS="-arch ppc" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

Leopard on an Intel machine:
sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

Snow Leopard (only on Intel):
sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

10.   That should do it.  You should now be able to return to your projects and run the rake db:migrate command without seeing the awful  "rake aborted! uninitialized constant MysqlCompat::MysqlRes"  error.

11. Many thanks to my Ruby on Rails Jedi friend RW for showing me this simple trick.  The force is powerful in that one :)