If you have tried to erase the contents of your Time machine backup (external drive) and received the “Cannot unmount disk” error – no fear. I too have received the error and resolved it by plugging the external drive into a different mac and used the disk utility to erase it. Don’t forget to choose the Max OS Extended (Journaled) option for Time Machine.
Fix the "Cannot unmount disk" error when erasing Time Machine backup
How to parse a response soap message using soap4r
Soap4r is a very helpful utility. Using ‘wsdl2ruby’ you can generate local methods to invoke web service methods via SOAP.
wsdl2ruby.rb --wsdl path_to_your_wsdl --type client | server
The only problem I had with soap4r during my implementation was the difficulty I had with manually parsing the soap response from the web service. Though the web service methods were generated perfectly, I needed additional information from the soap response (the soap header information, not to be confused with the http header info) that was not provided by the wsdl, thus left out of the wsdl2ruby code generation.
SOAP4r uses a private send_post method in the HTTPStreamHandler class of the SOAP module. In the send_post method an net/http instance uses the post method to post the message as a string to the whichever url was sent in the SOAP call. The post method returns the response from the remote server. However, HTTPStreamHandler does not make this available to you. To change all you need to do is make the response variable an instance variable.
The new res instance variable will return an HTTP::Message class. You will then need to access the body instance variable in the Body class. However, this will also need an accessor method monkey-patched through HTTP::Message::Body. (Also included below)
Monkey-patch the private send_post method in SOAP::HTTPStreamHandler to change the res local variable to an instance variable
module SOAP class HTTPStreamHandler attr_accessor :res private def send_post(url, conn_data, charset) conn_data.send_contenttype ||= StreamHandler.create_media_type(charset) if @wiredump_file_base filename = @wiredump_file_base + '_request.xml' f = File.open(filename, "w") f << conn_data.send_string f.close end extheader = {} extheader['Content-Type'] = conn_data.send_contenttype extheader['SOAPAction'] = "\"#{ conn_data.soapaction }\"" extheader['Accept-Encoding'] = 'gzip' if send_accept_encoding_gzip? send_string = conn_data.send_string @wiredump_dev << "Wire dumped:\n\n" if @wiredump_dev begin retry_count = 0 while true %{color:red}@res% = @client.post(url, send_string, extheader) if RETRYABLE and HTTP::Status.redirect?(@res.status) retry_count += 1 if retry_count >= MAX_RETRY_COUNT raise HTTPStreamError.new("redirect count exceeded") end url = @res.header["location"][0] puts "redirected to #{url}" if $DEBUG else break end end rescue @client.reset(url) raise end @wiredump_dev << "\n\n" if @wiredump_dev receive_string = @res.content if @wiredump_file_base filename = @wiredump_file_base + '_response.xml' f = File.open(filename, "w") f << receive_string f.close end case @res.status when 405 raise PostUnavailableError.new("#{ @res.status }: #{ @res.reason }") when 200, 202, 500 # Nothing to do. 202 is for oneway service. else raise HTTPStreamError.new("#{ @res.status }: #{ @res.reason }") end # decode gzipped content, if we know it's there from the headers if @res.respond_to?(:header) and !@res.header['content-encoding'].empty? and @res.header['content-encoding'][0].downcase == 'gzip' receive_string = decode_gzip(receive_string) # otherwise check for the gzip header elsif @accept_encoding_gzip && receive_string[0..1] == "\x1f\x8b" receive_string = decode_gzip(receive_string) end conn_data.receive_string = receive_string conn_data.receive_contenttype = @res.contenttype conn_data end end end module HTTP class Message::Body attr_accessor :body end end
After the monkey-patching, the response message will be accessible after invoking a web service method using the client class generated by wsdl2ruby. The response message will become available in the res accessor method through the streamhandler method of the client class that was generated by wsdl2ruby. The class will be called something like “ClientAPISoap” – this will be defined in the defaultDriver.rb file.
In my case:
driver = ClientAPISoap.new results = driver.some_ws_method(with_parameters).getResults #getResults is also a ws method raw_response_message = driver.streamhandler.res.body.body
You can then use REXML to parse whatever you need in the SOAP response message body.
How to test production rails exceptions while in development mode
Recently found an easy way to test rails exceptions raised in production while in development.
Though you could just as easily use:
script/server -e production
Short of that the following works perfectly:
Update config/development.rb
change:to:config.action_controller.consider_all_requests_local = false
config.action_controller.consider_all_requests_local = true
Then update controllers/application.rb
add as the last method (unless you have additional protected methods then add to those):
protected
def local_request?
false
end
This works because rails will check if a raised exception is a local request. If it is a local request the “development” mode error screen will be presented to you like this:

Otherwise the 500 or 404 error pages will be displayed to the user.
Both modifications are needed since there are two ways a request is considered local 1.) which is controlled in the config folder and 2.) A request is also considered local if the request is being served on the local machine (127.0.0.1).
Installing Ruby on Rails, mySQL and Rmagick on Leopard
I recently had to reinstall Ruby on Rails and Rmagick on Leopard. There is a lot of debate surrounding the best way to go – whether it be by source, by MacPorts, by Fink or by anything else I don’t know about yet.
I’ve gone the Macports route and have yet to regret it. As according to Paul Sturgess:
MacPorts (formerly known as DarwinPorts) is a package manager that will download, compile and install software, while installing any required dependencies, automatically. You can easily upgrade or deactivate packages you download, it just makes managing everything that much easier.
Quick points from Paul Sturgess:
Set up your path environment variables:
PATH="/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin"
Install mySQL, Ruby, and maybe Subversion:
sudo port selfupdate sudo port install mysql5 +server sudo port install ruby sudo port install rb-rubygems sudo port install rb-termios sudo port install rb-mysql sudo port install subversion +tools
Add a symbolic link to the mysql5 mysqld.sock:
sudo ln -s /opt/local/var/run/mysql5/mysqld.sock /tmp/mysql.sock
Make sure Mysql5 starts up whenever the machine is rebooted with:
sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist
Install Ruby on Rails and others:
sudo gem install -y rake sudo gem install -y rails sudo gem install -y capistrano sudo gem install -y mongrel sudo gem install -y mongrel_cluster
In addition, Educate. Liberate. provides the simple rules to follow to get Rmagick properly installed once you’re rolling on Rails goodness.
Quick points from Educate.Liberate.:
sudo port install tiff -macosx sudo port install ImageMagick sudo gem install rmagick
