Thursday, February 26, 2009

Failed attempt to use Mac OS X Leopard stock installation of Ruby on Rails.

Stock installation of RoR, if updated to Rails 2.2.2 fails because it breaks MySQL functionality. Using gem install mysql fails because the stock Ruby interpreter packaged with Xcode 3.0 is only 32 bit and the stock version of MySQL and its libraries for building mysql clients are 64 bit. Link to Chris Cruft's blog about MySQL gem problems

Faced the same error messages as in the blog above, and followed basically the same steps. Below is the initial error message when trying to install the mysql gem.

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb install mysql
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
*** extconf.rb failed ***


I tried both options indicated at the end of Chris Cruft's blog post, and the successful solution that ended up being the least amount of work was installing a 4-way fat universal binary for the MySQL.

The first option I attempted was to make a new installation of Ruby 1.8.7-p72 by compiling from source. Used /usr/local for new installation environment to avoid conflicts with stock installation. Added a ".profile" file in the shell users's home directory so that the $PATH environment variable would be set to PATH=/usr/local/bin:/bin:/usr/sbin:/sbin:/usr/bin:/usr/X11/bin
upon login. I followed most of these instructions to compile Ruby for Mac OS X Leopard

When I got to the step of installing the MySQL C binding gem for Rails; I still had the same problem as when attempting to install it for the out-of-the-box Ruby 1.8.6 stack.
Entering this in the terminal

sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

just didn't work and gave the following errors when using -V option with gem install.

ld: warning in /usr/local/mysql/lib/libmysqlclient.dylib, file is not of required architecture
ld: warning in /usr/local/mysql/lib/libmygcc.a, file is not of required architecture


Errno::ENOENT (No such file or directory - /tmp/mysql.sock):
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/vendor/mysql.rb:107:in `initialize'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/vendor/mysql.rb:107:in `new'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/vendor/mysql.rb:107:in `real_connect'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/connection_adapters/mysql_adapter.rb:527:in `connect'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/connection_adapters/mysql_adapter.rb:186:in `initialize'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/connection_adapters/mysql_adapter.rb:85:in `new'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/connection_adapters/mysql_adapter.rb:85:in `mysql_connection'


It then occurred to me that my colleague had recently built a new PHP environment and needed the MySQL client libraries and headers.

The following are the notes my colleague wrote for the PHP build.

More or less followed instructions from: http://www.unibia.com/unibianet/node/32?page=0,0
found a few difficulties along the way, and did not install my own apache to replace the apple one.

Started out building in intel 32 bit mode, but the apache was compiled in 64 bit and couldn't use it so had to restart the process - see lines 29-36 below.


First of all, we need to download the MySQL client libraries and headers from Apple's website since they are not included with Mac OS X Server 10.5. The following instructions are taken directly off of Apple's knowledge base article located at http://support.apple.com/kb/TA25017?viewlocale=en_US.

To install:

Download the file from: http://www.opensource.apple.com/darwinsource/other/MySQL-43.binaries.tar.gz
If the download doesn't automatically produce a folder on your desktop, double-click it to unzip it to a folder named "MySQL-43.binaries" which has a file named "MySQL-43.root.tar.gz" in it (as well as the readme file). Note: Do not double-click/unzip the "MySQL-43.root.tar.gz" file that is within the folder.
Open Terminal.
Type cd (but do not press Return).
Drag the "MySQL-43.binaries" folder from your desktop to the Terminal window to populate the cd path, then press Return.
Execute this command:

sudo tar -xzvf MySQL-43.root.tar.gz -C /
Make sure you complete this step, you can not build PHP with MySQL support without these libraries and headers.

Lets go to a terminal and switch to the root user and create ourselves a work folder to keep everything in. Execute the following commands in your terminal window:

sudo -s
cd ~
mkdir work
cd work


set some environment variables for the compilers:

# MACOSX_DEPLOYMENT_TARGET=10.5
# CFLAGS="-arch x86_64 -g -Os -pipe -no-cpp-precomp"
# CCFLAGS="-arch x86_64 -g -Os -pipe"
# CXXFLAGS="-arch x86_64 -g -Os -pipe"
# LDFLAGS="-arch x86_64 -bind_at_load"
# export CFLAGS CXXFLAGS LDFLAGS CCFLAGS MACOSX_DEPLOYMENT_TARGET


PHP GD depends on the libjpeg library, so lets install this at /usr/local/libjpeg. Download and extract as shown.

wget http://www.ijg.org/files/jpegsrc.v6b.tar.gz
tar xfvz jpegsrc.v6b.tar.gz
cd jpeg-6b/
The configure script will throw an error unless you copy some configuration hints from the libtool library to the libjpeg source files directory. The libtool library is already included in OS X. Execute the following commands to obtain those files.

cp /usr/share/libtool/config.sub .
cp /usr/share/libtool/config.guess .
Configure and make, notice how we specify the install directory with PREFIX. You must compile libjpeg with the shared option, thus we use the "--enable-shared" flag.

./configure --prefix=/usr/local/libjpeg --enable-shared
make
Since this is such an old library, it won't automatically create the destination directories, you must do that manually before attempting to install.

mkdir -p /usr/local/libjpeg/include
mkdir -p /usr/local/libjpeg/bin
mkdir -p /usr/local/libjpeg/lib
mkdir -p /usr/local/libjpeg/man/man1
Now you can install and return to the work folder

make install
cd ..



Build and Install FreeType2
Some features of the GD library won't be enabled unless you have freetype2 installed. Download, extract, configure, build, and install to "/usr/local/freetype2" as shown.

wget http://savannah.inetbridge.net/freetype/freetype-2.3.8.tar.gz
tar xfvz freetype-2.3.8.tar.gz
cd freetype-2.3.8
./configure --prefix=/usr/local/freetype2
make
make install
cd ..



Build and Install GD
Download, extract, configure, build, and install libgd to "/usr/local/gd" as shown. Notice how we tell libgd where to find libjpeg and freetype2.

wget http://www.libgd.org/releases/gd-2.0.35.tar.gz
tar xfvz gd-2.0.35.tar.gz
cd gd-2.0.35
./configure --prefix=/usr/local/gd --with-jpeg=/usr/local/libjpeg --with-freetype=/usr/local/freetype2
make
make install
cd ..



Build and Install libmcrypt
Lots of PHP application want mcrypt (phpMyAdmin for example), so lets go ahead and get the mcrypt library setup. PHP recommends that you specify the following flags, "--disable-posix-threads" and "--enable-dynamic-loading".

Download, extract, configure, build, and install to "/usr/local/mcrypt" as shown.

wget http://voxel.dl.sourceforge.net/sourceforge/mcrypt/libmcrypt-2.5.8.tar.gz
tar xfvz libmcrypt-2.5.8.tar.gz
cd libmcrypt-2.5.8
./configure --prefix=/usr/local/mcrypt --disable-posix-threads --enable-dynamic-loading
make
make install
cd ..

Actually this one gave me grief, so I found I had to add --disable-dependency-tracking to the .configure command to get past the error of you can only compile for one architecture at a time. This took several tries and was not entirely a satisfying resounding "you got it right" result.



Build and Install PHP
It's time to build PHP. There are tons of configure options available, I have selected the most used. You may take a look at all available options by using the "--help" flag when you run the configure script. Keep in mind however, that some options may require additional dependencies not discussed here.

Download and Extract the latest PHP source code

wget http://us.php.net/get/php-5.2.8.tar.gz/from/this/mirror
tar xfvz php-5.2.8.tar.gz
cd php-5.2.8
Along with the desired features we want PHP to have, we must tell it where to find libgd, mcrypt, Apache, MySQL Client, libjpeg, and freetype2. Additionally, we must tell PHP where to find some of the Apple built in libraries. Thus we have a long and complex configure command as shown.

./configure --prefix=/usr/local/php5 --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr --with-mysql-sock=/var/mysql --with-mysqli=/usr/bin/mysql_config --with-zlib-dir=/usr --with-iodbc=/usr --with-curl=/usr --with-xsl=/usr --with-jpeg-dir=/usr/local/libjpeg --with-gd=/usr/local/gd --with-freetype-dir=/usr/local/freetype2 --with-mcrypt=/usr/local/mcrypt --enable-cli --enable-exif --enable-ftp --enable-mbstring --enable-mbregex --enable-sockets --with-openssl --with-xmlrpc --with-pear
Once PHP's make file is configured, lets build and install

make
make install
PHP will automatically modify the httpd.conf file in your Apache installation, but it won't add the application type. We'll take care of that part later.

once again I modified the .configure command a little: this is what I ended up with:
./configure --prefix=/usr/local/php5 --with-apxs2=/usr/sbin/apxs --with-openssl=/usr --with-zlib=/usr --with-zlib-dir=/usr --with-iodbc=/usr --with-gd=/usr/local/gd --with-ldap --with-xmlrpc --enable-exif --enable-soap --enable-sqlite-utf8 --enable-cli --enable-wddx --enable-ftp --enable-sockets --with-bz2=/usr --enable-zip --enable-pcntl --enable-shmop --enable-sysvsem --enable-sysvshm --enable-sysvmsg --enable-memory-limit --enable-mbstring --enable-mbregex --enable-sockets --enable-bcmath --enable-calendar --enable-memcache --with-kerberos=/usr --with-imap-ssl=/usr --with-libxml-dir=shared,/usr/ --with-xsl=shared,/usr --with-curl=shared,/usr --with-jpeg-dir=/usr/local/libjpeg --enable-gd-native-ttf --with-freetype-dir=/usr/local/freetype2 --with-mysql=shared,/usr/local/mysql --with-mysql-sock=/var/mysql --with-mysqli=shared,/usr/bin/mysql_config --with-mcrypt=shared,/usr/local/mcrypt --with-pear

the imap support flag was causing errors so I had to drop imap support for now.



edited the php.ini - put the working version in: /usr/local/php5/lib/php.ini

copied some mysql libraries, because it was looking for them in the wrong place. the copies are in /usr/local/php5/lib/mysql - the originals were in /usr/local/mysql and still are there.


I noticed in my colleague's configure for PHP 5, he pointed to the mysql_config at /usr/bin and not the one located in /usr/local/mysql. Also, I investigated the MySQL-43.binaries.tar.gz he downloaded. The instructions he followed meant that mysql binaries located in /usr/bin were replaced.

By executing /usr/bin/mysqlbug and /usr/local/mysql/bin/mysqlbug I was able to determine the configuration options of these mysql libraries and compare them. I discovered that the MySQL binaries in /usr/bin were from the mysql-5.0.45 (Source distribution) release and the binaries in /usr/local/mysql/bin were from the mysql-5.0.77 (MySQL Community Server (GPL)) release.

/usr/bin contained 4-way fat universal mysql binaries compiled with
CFLAGS=-O3 -fno-omit-frame-pointer -arch ppc -arch ppc64 -arch i386 -arch x86_64 -pipe
and the binaries in /usr/local/mysql/bin were just for 64-bit Intels compiled with
CFLAGS=-g -Os -arch x86_64 -fno-common

Ultimately, the solution was to use the fat mysql-5.0.45 release and the command to install the MySQL C binding was
gem install mysql -- --with-mysql-config=/usr/bin/mysql_config
This worked for both the stock Ruby on Rails stack and the /usr/local Ruby on Rails build.

Monday, February 23, 2009

Playing with SOAP in Ruby on Rails using WSDL Driver Factory

-First, a little background on why I am using RoR and SOAP.
When I helped design and build an inventory and booking system circa 2007, my role was basically systems/business analyst. I also provided the impetus that we build the system using tools beyond simple "procedural" PHP/javascript, and that we look for a web application technology platform which would allow us to rapidly build a system that stored everything in a relational database.

Back in 2001, I wondered why I had to write SQL queries for web applications when I knew that if I was working with a well-designed database, there should be techniques to generate queries or even better... a developer could write objects that were basically entities from an ERD and actors from a UML and these objects knew which other objects were related to it and had methods to access all the information without having to write any SQL or be intimately aware of the relationships between tables.

So for our inventory and booking system, our developer found the Ruby on Rails (RoR) framework, which implements MVC architecture. This framework fit my requirements that we don't have to be writing lots of SQL and that we should use an agile method of software development. Eventually, our inventory and booking system was built with RoR and AJAX technologies but my role in its creation did not involve any coding.

Today, I need to build a system to integrate two applications, one that exposes a SOAP API and one that provides decent docoumentation to directly access the database.
-End Background

As a complete newbie to writing code for SOAP and for Ruby on Rails, I have encountered many challenges and tackled problems that an experienced RoR developer would have solved readily. It doesn't help that programming is merely a hobby of mine by necessity, and that I haven't written any serious code in years.

By the end of this post some of the most valuable websites available for someone trying to use RoR to consume SOAP services will be linked and referenced.

Starting with the WSDL Driver Factory standard library by using Ryan Heath's Consuming SOAP services in Ruby example. And similar examples.

The goal was to use his code in a model-view-controller architecture and being a novice, I had a lot of difficulty. I ended up with the following proof of concept; with minimal coding, RoR can consume a simple SOAP webservice. The specific webservice consumed in this example is one that calculates the amortized payment amount per period given the required parameters. I found this webservice on www.xmethods.net, and the developer appears to have implemented it in ColdFusion. Notice in this example, the class Amortization extends ActiveRecord, so the database is used to store persistent data, which may be useful if retaining a history of request inputs and response outputs from consuming a SOAP service is important.

This is the model file: amortization.rb

require 'soap/wsdlDriver'

class Amortization < ActiveRecord::Base

def amortization
@amortization ||= wsdl.create_rpc_driver.calculate principal, interest, num_payments
end

private
def wsdl
SOAP::WSDLDriverFactory.new(url)
end
end

This is the controller file: amortizations_controller.rb

class AmortizationsController < ApplicationController

def new
@amortization = Amortization.new :url => 'http://www.kylehayes.info/webservices/AmortizationCalculator.cfc?wsdl'
end

def create
@amortization = Amortization.new params[:amortization]
if @amortization.save
redirect_to @amortization
# redirect_to :action => 'index'
else
render :action => 'new'
end
end

def show
@amortization = Amortization.find params[:id]
end

def index
@amortizations = Amortization.find(:all)
end

def delete
@amortizations = Amortization.find(params[:id])
@amortizations.destroy
redirect_to :action => 'index'
end

end

Below are the views in the views/amortizations folder.

Beginning with new.html.erb


<h1>Consume a SOAP Web Service</h1>

<% form_tag :action => 'create' do %>

<p>
<label for="amortization_WSDL_URL">Amortization WSDL URL</label><br/>
<%= text_field 'amortization', 'url', :value => @amortization.url %>
</p>
<p>
<label for="amortization_principal">Principal Amount</label><br/>
<%= text_field 'amortization', 'principal' %>
</p>
<p>
<label for="amortization_interest">Interest (not in percent)</label><br/>
<%= text_field 'amortization', 'interest' %>
</p>
<p>
<label for="amortization_num_payments">Number of Payments</label><br/>
<%= text_field 'amortization', 'num_payments' %>
</p>
<p>
<%= submit_tag "Store inputs to Amortization calculator" %>
</p>
<% end %>

<%= link_to 'Back', {:action => 'index'}%>

show.html.erb

<p>
<b>SOAP Web Service Response:</b> $
<%=h @amortization.amortize %>
</p>

index.html.erb

<h1>Listing services</h1>

<table>
<tr>
<th>Amortization per period - click URL to calculate</th>
<th>Principal Amount</th>
<th>Interest Rate (not in percent)</th>
<th>Number of Payment periods</th>
</tr>

<% if @amortizations.blank? %>
<p>no amortizations in system</p>
<% else %>

<% @amortizations.each do |a| %>
<tr>
<td><%= link_to a.url, a -%></td>
<td><%=h a.principal -%></td>
<td><%=h a.interest -%></td>
<td><%= link_to a.num_payments, {:action => 'show', :id => a.id} -%></td>
<td><%= link_to 'Delete', {:action => 'delete', :id => a.id}, :confirm => 'Are you sure?' %></td>
</tr>
<% end %>
<% end %>
</table>

<br />

<%= link_to 'New amortization', {:action => 'new'}%>

You will need to add the following to the routes file found in config/routes.rb.

map.resources :amortizations

Also, create a migration for creating amortizations table in the database using the file below and run rake db:migrate

class CreateAmortizations < ActiveRecord::Migration
def self.up
create_table :amortizations do |t|
t.column :url, :string
t.column :principal, :decimal
t.column :interest, :decimal
t.column :num_payments, :decimal
t.timestamps
end
end

def self.down
drop_table :amortizations
end
end


In the next code sample, the data is not persistent and Amortization is not a subclass of Active Record. This could be useful, for example, when calling authentication methods of a webservice where you would not want to store the username/password. Thanks to the people in the Ruby on Rails IRC channel, the first method only needed minor modifications. Check out the channel #rubyonrails on irc.freenode.net.

The model, amort.rb

require 'soap/wsdlDriver'

class Amort
attr_accessor :url, :principal, :interest, :num_payments

def initialize(options = {} )
self.url = options[:url]
self.principal = options[:principal]
self.interest = options[:interest]
self.num_payments = options[:num_payments]
end

def data
%w(url principal interest num_payments).inject({}) do |acc, method|
acc.merge! method.to_sym => send(method)
end
end

def print_response
@soap = wsdl.create_rpc_driver
response = @soap.calculate(principal, interest, num_payments)
return response
end

private
def wsdl
SOAP::WSDLDriverFactory.new(url)
end
end

The controller, amorts_controller.rb

class AmortsController < ApplicationController

def new
@amort = Amort.new :url => 'http://www.kylehayes.info/webservices/AmortizationCalculator.cfc?wsdl'
end

def create
@amort = Amort.new params[:amort]
redirect_to url_for(:action => :show, :amort => @amort.data)
end

def show
@amort = Amort.new params[:amort]
end

end

new.html.erb

<h1>Consume a Web Service</h1>

<%= form_tag :action => 'create' %>
<p>
<label for="amort_WSDL_URL">Amortization WSDL URL</label><br/>
<%= text_field 'amort', 'url', :value => @amort.url %>
</p>
<p>
<label for="amort_principal">Principal Amount</label><br/>
<%= text_field 'amort', 'principal' %>
</p>
<p>
<label for="amort_interest">Interest (not in percent)</label><br/>
<%= text_field 'amort', 'interest' %>
</p>
<p>
<label for="amort_num_payments">Number of Payments</label><br/>
<%= text_field 'amort', 'num_payments' %>
</p>
<p>
<%= submit_tag "Create" %>
</p>

<%= link_to 'Back', amorts_path %>

show.html.erb

<p>
<b>The amortized payment per period is:</b>
<%=h @amort.print_response %>
</p>


<%= link_to 'Edit', edit_amort_path(@amort) %> |
<%= link_to 'Back', amorts_path %>

Don't forget to add a RESTful route for amorts into the routes.rb file. There is extra code in this sample, ie. the create method for the controller is not necessary and could be bypassed without a loss of functionality simply by changing the :action => 'create' in the new template to :action => 'show'

Other resources:
Another example
Ruby Standard Library Documentation (RDoc)
The full source of SOAP4R with examples is available at the "trac"-ing site

IRC:
If you want to use a controller method in a view, in the controller you need to specify helper_method :use_web_service, then you can call use_web_service in your views directly. That won't pass in a params hash, though, so you're better off creating a method that takes an array of arguments, and calling that from your use_web_service action and your views.

[code]Try at refactoring... http://pastie.org/398113[/code]

Friday, February 20, 2009

How to use Ruby on Rails to integrate with a legacy database while leveraging scaffolding.

I am trying to be as lazy as possible...

rails_app $ rails independentreps -d mysql
Edit config/database.yml with specific database name, host, username, password. Add additional environment records if required. For example:

development:
adapter: mysql
encoding: utf8
database: indrep_development
pool: 5
username: root
password: pw
host: localhost

test:
adapter: mysql
encoding: utf8
database: indrep_test
pool: 5
username: ...
...
production:
...
database: indrep_production
...
## Additional Environment Records
legacy_production:
adapter: mysql
encoding: utf8
database: reps_db
pool: 5
username: admin
password: letmein
host: 192.168.0.10
port: 13540

From within the application folder, use the generation features of the Ruby on Rails framework
rails_app $ ruby script/generate model Client
rails_app $ ruby script/generate scaffold Client
So scaffolding is generated for the first time.


Next, edit app/models/client.rb with set_table_name, set_primary_key with actual identifiers from legacy database
rails_app $ script/console
>> Client
=> will spit out Ruby-friendly style of describing table schema/model, i.e. Client model. Copy this result to clipboard.
>> exit
rails_app $ rm app/helpers/clients_helper.rb


So we generate scaffolding again, but this time with value-added features of our schema/model attributes.
rails_app $ ruby script/generate scaffold Client <Paste model attributes from clipboard here.> However take out the commas between attributes, and the spaces between the attribute and datatype.
replace files if asked.
rails_app $ mongrel_rails start -d
visit http://localhost:3000/Clients

Why do we generate scaffold twice instead of just once? There is no logical reason for it when the first run creates the controller.rb and view templates (index, new, show, edit), while the second run would do the same, only with the attributes all spelled out. Why not just edit the model client.rb with the legacy table information before running script/generate scaffold? Well for some reason if scaffolding is not generated twice, you will end up with the following error:

ActionController::RoutingError in Clients#index

instead of nice table rows with Show Edit Destroy working links.

I know that generating scaffold twice will add the line map.resoures :clients twice to the config/routes.rb file. But manually duplicating that line in routes.rb does not solve the problem.
One day, when I have the time and am able to understand Ruby better I'll take a look at this article about route generation. I figure it will explain this strange behaviour.
The following shows a part of the Full Trace response generated by this strange problem.

client_url failed to generate from {:action=>"show", :controller=>"clients", :id=>#<Client pkId: 2, Name: "Make It Work Enterprises"...

Extracted source (around line #57):
56: <td><%=h client.IDamandar %></td>
57: <td><%= link_to 'Show', client %></td>
58: <td><%= link_to 'Edit', edit_client_path(client) %></td>

/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/routing/route_set.rb:377:in `raise_named_route_error'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/routing/route_set.rb:341:in `generate'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/url_rewriter.rb:208:in `rewrite_path'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/url_rewriter.rb:187:in `rewrite_url'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/url_rewriter.rb:165:in `rewrite'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/base.rb:626:in `url_for'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/helpers/url_helper.rb:85:in `send'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/helpers/url_helper.rb:85:in `url_for'
(eval):16:in `client_path'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/polymorphic_routes.rb:112:in `__send__'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/polymorphic_routes.rb:112:in `polymorphic_url'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/polymorphic_routes.rb:119:in `polymorphic_path'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/helpers/url_helper.rb:91:in `url_for'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/helpers/url_helper.rb:228:in `link_to'
app/views/clients/index.html.erb:107
app/views/clients/index.html.erb:56:in `each'
app/views/clients/index.html.erb:56
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/renderable.rb:39:in `send'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/renderable.rb:39:in `render'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/template.rb:73:in `render_template'
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/base.rb:256:in `render'

Sunday, February 15, 2009

A quick update on installing and running VMware Server on Vista 32-bit

I had only very minor experience with VMware, having only firsthand experience with it on an iMac with VMware Fusion beta installed. The iMac ran Mac OS X 10.4 and VMware Fusion was used to host a Windows XP guest OS. It ran very slowly, possibly due to the lack of Intel VT-x (Virtualization Technology) on the model of Intel Core 2 Duo. Also, the iMac only had 1 GB of RAM.

In early February, 2009, I was compelled to install VMware on my laptop to run a Linux server environment. The laptop is an ASUS F8Sn-B1 with an Intel T8100 and 3GB of RAM. My hope was that performance on this machine would not be a problem.

This is just a distillation of some of the issues I discovered while preparing to do the installation. There are several VMware Products, it used to be that the versions you wanted to download were the beta versions (Fusion for Mac, or Server beta). Those versions you could download, install, and run a VMware host for free indefinitely. Now, VMware Server 2.0 is out of beta. The version available at the time is 2.0.0 build 122956 and it is a simple matter to register at www.vmware.com to download this free version.
With this new release there are now only a few things to be careful of during installation. The beta versions had a lot more problems even though this latest version still doesn't officially support Vista as a host.
1. Before installation, reboot your machine to allow the installation of unsigned drivers. You will have to hold F8 or F5 or in my laptop's case, repeatedly hit F1 right after the BIOS POST beep to enter the Windows Boot Advanced Options Menu. Once there choose: Disable Driver Signature Enforcement. Links to references: http://www.cubert.net/2008/07/installing-vmware-server-106-on-windows.html
http://forum.xcpus.com/operating-systems/5767-howto-use-unsigned-drivers-under-vista-x64.html
2. Disable UAC (User Account Control) and any overprotective antivirus software prior to installation.

I had basically very few problems installing and getting VMware Server running a guest OS. Compared to the multitude of problems other people have had trying to run the beta versions, my experience was a breeze. I didn't have any "freeze" up issues or virtual memory problems that others had. Performance for me has been wonderful and much faster than on the iMac setup I tried earlier. The non-beta release really seems to be a step in the right direction.

Other references:
http://blog.xebia.com/2008/12/13/running-vmware-server-20-on-windows-vista-with-proper-performance/
VMware on Vista Lameness