Aug 15 2010

Changing Column Order via ActiveRecord Migration

Is it possible to change the order of the columns in your MySQL (or other database) table using a migration? Lets see.

If you check the ActiveRecord::Migration documentation you’ll see there is a method called ‘change_column’ which accepts various options.

change_column(table_name, column_name, type, options): Changes the column to a different type using the same parameters as add_column

As of Rails 2.3.6 this is now available by using the :after option. You’ll have to include the field type, even though you are not modifying the type.

Example:

change_column :orders, :tax_rate, :float, :after => :tax_state




Aug 9 2010

Rails Performance Statistics

Again, as I search for things, I stumble onto new tools. I just found out about a tool for monitoring the performance of Java and Ruby applications called New Relic.

They provide a free service level for Startups and Students even.




Aug 9 2010

RailRoad Gem

I just discovered that there is a Ruby gem which generates diagrams based on Rails models (ActiveRecord). I ran across this website a while back, but didn’t quite connect the dots. I was just reading an article on placing models into their own namespace, and I realized that the diagram it uses as an example was generated using RailRoad.

http://railroad.rubyforge.org/


Aug 7 2010

Annotate Models

There is a rails plugin which adds schema information for the models in comments at the top of your model definition files. It’s really useful. Check out the instructions on installing and using this plugin at:

http://pragdave.pragprog.com/pragdave/2006/02/annotate_models.html


Jul 27 2010

Undefined method ‘ref’ for ActiveSupport::Dependencies:Module

After upgrading to Snow Leopard, and trying to run ‘rake db:migrate’, I received this error once. This seems common to others which have upgraded, especially back when Snow Leopard was released in August of 2009:

rake aborted!
uninitialized constant MysqlCompat::MysqlRes
(See full trace by running task with --trace)

I’ve tried to troubleshoot by reinstalling the MySQL gem, and the 64 bit version of the MySQL server. I’m no longer receiving this error above.

When installing the MySQL Gem, I receive a bunch of errors, unless I specify to not install documentation.


$ sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/opt/local/lib/mysql5/bin/mysql_config
Building native extensions.  This could take a while...
Successfully installed mysql-2.8.1
1 gem installed
Installing ri documentation for mysql-2.8.1...

No definition for next_result

No definition for field_name

No definition for field_table

No definition for field_def

No definition for field_type

No definition for field_length

No definition for field_max_length

No definition for field_flags

No definition for field_decimals

No definition for time_inspect

No definition for time_to_s

No definition for time_get_year

No definition for time_get_month

No definition for time_get_day

No definition for time_get_hour

No definition for time_get_minute

No definition for time_get_second

No definition for time_get_neg

No definition for time_get_second_part

No definition for time_set_year

No definition for time_set_month

No definition for time_set_day

No definition for time_set_hour

No definition for time_set_minute

No definition for time_set_second

No definition for time_set_neg

No definition for time_set_second_part

No definition for time_equal

No definition for error_errno

No definition for error_sqlstate
Installing RDoc documentation for mysql-2.8.1...

No definition for next_result

No definition for field_name

No definition for field_table

No definition for field_def

No definition for field_type

No definition for field_length

No definition for field_max_length

No definition for field_flags

No definition for field_decimals

No definition for time_inspect

No definition for time_to_s

No definition for time_get_year

No definition for time_get_month

No definition for time_get_day

No definition for time_get_hour

No definition for time_get_minute

No definition for time_get_second

No definition for time_get_neg

No definition for time_get_second_part

No definition for time_set_year

No definition for time_set_month

No definition for time_set_day

No definition for time_set_hour

No definition for time_set_minute

No definition for time_set_second

No definition for time_set_neg

No definition for time_set_second_part

No definition for time_equal

No definition for error_errno

No definition for error_sqlstate

I’ve realized that these errors don’t occur if you try to install without documentation included.


$ sudo env ARCHFLAGS="-arch x86_64" gem install mysql --no-ri --no-rdoc -- --with-mysql-config=/opt/local/lib/mysql5/bin/mysql_config
Building native extensions.  This could take a while...
Successfully installed mysql-2.8.1
1 gem installed

I doubted if this really was a successful installation due to the errors when including the documentation, but this isn’t the case.

You’ll notice that I’m running MySQL from the installation location in /opt/local/lib/mysql5/. This is because I’m using MacPorts, and I definitely do not want to try to run from a mixed environment with some executables and gems being installed under my system folders and library locations, and others under the location of the folders where MacPorts installs these things. Why? Because I read that some people have had problems with 32 bit versions of some libraries and executables still being installed and this causing dependency conflicts. I’m needing certain packages provided by MacPorts, so I’m trying to ensure that my entire environment is based on MacPort packages.


jason-imac:bin jason$ file `which ruby`
/opt/local/bin/ruby: Mach-O 64-bit executable x86_64
jason-imac:bin jason$ file `which mysql`
/opt/local/bin/mysql: Mach-O 64-bit executable x86_64

I’ve completely uninstalled all the gems I had installed. I’m only working on one new project, so luckily I have no dependencies on all these old gems. I even removed all the gems which came with the system by default. Now all the gems are installed based on the MacPorts version of Ruby I’m running.


$ sudo gem list -d | grep Installed
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8
    Installed at: /opt/local/lib/ruby/gems/1.8

When I run a migration I still received an error. I doubted that the MySQL gem is installed properly, but this I can’t be completely sure of. No one else has reported this error, so I’m really stuck.


$ rake db:migrate
(in /Users/jason/rj4)
rake aborted!
undefined method `ref' for ActiveSupport::Dependencies:Module

(See full trace by running task with --trace)

Finally I realized that this error was the result of some issue with the Devise gem which my co-worker installed for user authentication. I found this Google Groups posting about the same error.

I installed devise version 1.0.8 and this resolved the issue.


$ sudo gem install devise -v=1.0.8
Successfully installed devise-1.0.8
1 gem installed
Installing ri documentation for devise-1.0.8...
Installing RDoc documentation for devise-1.0.8...

$ rake db:migrate
(in /Users/jason/rj4)
rake aborted!
Unknown database 'rj4_development'

(See full trace by running task with --trace)
jason-imac:rj4 jason$ rake db:create
(in /Users/jason/rj4)
jason-imac:rj4 jason$ rake db:migrate
(in /Users/jason/rj4)
==  CreateProperties: migrating ===============================================
-- create_table(:properties)
   -> 0.0712s
==  CreateProperties: migrated (0.0713s) ======================================

==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0967s
==  CreateUsers: migrated (0.0969s) ===========================================

Jul 20 2010

Setting up Deployment for Rails using Capistrano, Apache with Passenger and Git

I don’t have time right now to learn how to setup Capistrano. I just want a recipe that works and does the job. Here are my notes.

1) First install the Capistrano gem

sudo gem install capistrano

2) Next you need to go into the directory of your Ruby on Rails application and capify it:

capify .

3) Next I recommend this article (I’ll rip off the deploy.rb soon and post it here)

http://www.zorched.net/2008/06/17/capistrano-deploy-with-git-and-passenger/

4) Once you’ve configured your deploy.rb, run this command to have it setup the directories on the remote server (releases, shared, logs, etc).

cap deploy:setup

5) Next run this command to get the list of other capistrano commands you can run:

cap -T

The output should look like

cap deploy               # Deploys your project.
cap deploy:check         # Test deployment dependencies.
cap deploy:cleanup       # Clean up old releases.
cap deploy:cold          # Deploys and starts a `cold' application.
cap deploy:migrate       # Run the migrate rake task.
cap deploy:migrations    # Deploy and run pending migrations.
cap deploy:pending       # Displays the commits since your last deploy.
cap deploy:pending:diff  # Displays the `diff' since your last deploy.
cap deploy:restart       # Restarting mod_rails with restart.txt
cap deploy:rollback      # Rolls back to a previous version and restarts.
cap deploy:rollback:code # Rolls back to the previously deployed version.
cap deploy:setup         # Prepares one or more servers for deployment.
cap deploy:start         # start task is a no-op with mod_rails
cap deploy:stop          # stop task is a no-op with mod_rails
cap deploy:symlink       # Updates the symlink to the most recently deployed ...
cap deploy:update        # Copies your project and updates the symlink.
cap deploy:update_code   # Copies your project to the remote servers.
cap deploy:upload        # Copy files to the currently deployed version.
cap deploy:web:disable   # Present a maintenance page to visitors.
cap deploy:web:enable    # Makes the application web-accessible again.
cap invoke               # Invoke a single command on the remote servers.
cap shell                # Begin an interactive Capistrano session.

Jul 16 2010

Rake Tasks

If you’re wanting to know which Rake tasks are available for you to use from the command line, simply use this command:

rake -T

It will output a list of options, here are the first few I was shown:

rake db:abort_if_pending_migrations       # Raises an error if there are pending migrations
rake db:charset                           # Retrieves the charset for the current environment's database
rake db:collation                         # Retrieves the collation for the current environment's database
rake db:create                            # Create the database defined in config/database.yml for the current RAILS_ENV
rake db:create:all                        # Create all the local databases defined in config/database.yml
rake db:drop                              # Drops the database for the current RAILS_ENV
rake db:drop:all                          # Drops all the local databases defined in config/database.yml

A really useful one is the ‘routes’ option which outputs a list of the routes configured.

macbook:railsproject jason$ rake routes
(in /Users/jason/railsproject)
  /:controller/:action/:id
  /:controller/:action/:id(.:format)

Jul 16 2010

MySQL Gem Installation on Mac 10.5.8 – 64 bit ??

I’m setting up a new Ruby on Rails application, and tried to run the first migration for the creation of the new database. This failed because I didn’t have the MySQL gem installed. I’m using a 64 bit processor (Intel Core 2 Duo) so I installed the 64 bit MySQL for 10.5.8 (Leopard, I haven’t upgraded to Snow Leopard yet).

When trying to run the installation command I received an error:

$ sudo gem install mysql
Password:

Building native extensions.  This could take a while...
ERROR:  Error installing mysql:
	ERROR: Failed to build gem native extension.

/opt/local/bin/ruby extconf.rb
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lmygcc... no
checking for mysql_query() in -lmysqlclient... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

I looked online for a solution to this, and found that you have to point to the directory where MySQL is installed. I tried:

sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql

This resulted in this error instead:

Building native extensions.  This could take a while...
ERROR:  Error installing mysql:
	ERROR: Failed to build gem native extension.

/opt/local/bin/ruby extconf.rb --with-mysql-dir=/usr/local/mysql
checking for mysql_ssl_set()... no
checking for rb_str_set_len()... no
checking for rb_thread_start_timer()... no
checking for mysql.h... no
checking for mysql/mysql.h... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Since the error is reporting that it can’t find mysql.h (header file), I take it that the MySQL installer didn’t include the header files. From the command line if I go to /usr/local/mysql/include I see the mysql.h right in there.

I removed the preference panel option by opening the System Preferences, then holding CTRL and clicking on the MySQL option. This gave me an option to click on to remove it. I then deleted /usr/local/mysql and /usr/local/mysql-5.1.48-osx10.5-x86_64

sudo rm -rf /usr/local/mysql
sudo rm -rf /usr/local/mysql-5.1.48-osx10.5-x86_64/

Someone else mentioned something about using the 32-bit version of MySQL, so I downloaded it and installed it instead (hoping it doesn’t conflict with the processor I’m using). It installed and started up just fine. I ran the command to install the MySQL Gem again:

$ sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
uilding native extensions.  This could take a while...
Successfully installed mysql-2.8.1
1 gem installed
Installing ri documentation for mysql-2.8.1...

No definition for next_result

No definition for field_name

.
.
.
No definition for error_sqlstate
Installing RDoc documentation for mysql-2.8.1...

No definition for next_result

No definition for field_name
.
.
.
No definition for error_sqlstate

Finally it installed just fine.


Mar 13 2009

Database Schema Information

It can be very useful to have the database table schema information available to you when you are working on a model in a Ruby on Rails application. There is a plugin available which provides the schema information in comments at the top of each model called Annotate Models Plugin.


# == Schema Information
# Schema version: 20090215021706
#
# Table name: orders
#
# id :integer(11) not null, primary key
# order_number :integer(11) default(0), not null
# created_on :datetime
# shipped_on :datetime
# order_user_id :integer(11)
# order_status_code_id :integer(11) default(1), not null
# notes :text
# referer :string(255)
# order_shipping_type_id :integer(11) default(1), not null
# product_cost :float default(0.0)
# shipping_cost :float default(0.0)
# tax :float default(0.0), not null
# auth_transaction_id :string(255)
# promotion_id :integer(11) default(0), not null
# shipping_address_id :integer(11) default(0), not null
# billing_address_id :integer(11) default(0), not null
# order_account_id :integer(11) default(0), not null
# subscription_id :integer(11)

You can install the plugin using the following command from the root of your Rails application.

script/plugin install http://repo.pragprog.com/svn/Public/plugins/annotate_models

After you are done installing the plugin, simply run the rake task by using this command:

rake annotate_models