# Delayed Job missing method in production fixed

A few months ago I had an issue
with phusion passenger not starting due to a missing delayed job method. Yesterday I finally got round to figuring out why. Turns out that the delayed job gem was being loaded in the rails assets group in the Gemfile which of course are not used in production. Usually it only takes an hour or 2 away from the keyboard to spot these things. This time it seems there were a lot of trees obscuring the wood.

# handle_asynchronously missing method with delayed job and passenger: ‘require’ needed

We use delayed job in lots of our applications to handle long running tasks but we came across a weird issue when deploying our explorer2 rails app on apache using passenger. Passenger would throw out a 500 with ‘missing method handle_ayncronously’ whenever the application was accessed. Commenting out the handle_asynchronously part in the class (one of the models) and all would work fine. Running in development all was perfect and delayed job worked without a hitch. To see if we could replicate it we created the most basic rails app possible with one model with a method that used handle_asynchronously and guess what……it did not work either. Really left us a bit stumped how to solve it until I had the idea to use require 'delayed_job' in the model class using it. Then everything worked again.
So, we have the solution but we are not really sure what the cause is. The problem occurs in ruby 1.8 or 1.9 with rails 2.3.12 or 2.3.13 and delayed job 4.0.0 or 3.0.5 (via delayed job active record). However, we have code that uses handle_asynchronously (eg the original openPHACTS gui) in the exact same way without a hitch! Anyway, I thought that bundler etc meant that ‘require’ was no longer required but be warned….

# Rubygems, bundler and ssl error

I experienced a ‘Could not verify the SSL certificate for https://rubygems.org/’ error when doing a bundle install on OSX with RVM recently. A bit of googling revealed that there was a good chance that the CA certificates that curl uses were out of date

Solution:
Update rubygems gem update --system
Update RVM rvm get head
List certificate status rvm osx-ssl-certs status all
Update certificates rvm osx-ssl-certs update all

RVM was 1.18.15 before the update and 1.21.7 after the update.

# Ember JS: Ruby gem version hell

We are used to adding a gem to our Gemfile and just quietly getting on with things. However. with Ember things are not that easy. It is a moving target and you may see things like

Uncaught Error: assertion failed: Ember Handlebars requires Handlebars 1.0.0-rc.3 or greater. Include a SCRIPT tag in the HTML HEAD linking to the Handlebars file before you link to Ember.

and

Uncaught Error: assertion failed: Ember Views require jQuery 1.8, 1.9 or 2.0

Ember seems to have some difficulty figuring out what version numbers it can actually use: eg 1.0.0 is greater than 1.0.0.rc.3 but not to Ember. I have had to freeze handlebars-assets at 0.12.0 and jquery-rails at 2.2.1 to get round these issues. I have seen this with Ember 1.0.0.rc-6 and earlier. Be careful. One day things will hopefully get a lot simpler but until then keep your eyes open for version incompatibilities. There may be later versions of these gems that are compatible but these were versions that I know worked for me.

Update: I played around with all the gems and libraries and found that with Ember 1.0.0 rc6 you can use handlebars_assets 0.12.3. This in turn uses handlebars 1.0.0-rc.4. I also saw from the handlebars_assets github page that you can tell it to use specific versions of handlebars with

HandlebarsAssets::Config.compiler = 'my_handlebars.js' # Change the name of the compiler file
HandlebarsAssets::Config.compiler_path = Rails.root.join('app/assets/javascripts') # Change the location of the compiler file

# Ruby on Rails and IIS on Windows 7

Here are the steps I needed to install ruby 1.8, rails 2.3, sqlserver to run our https://github.com/myGrid/methodbox codebase on a Windows 7 platform and run it all under IIS. It should also work for any rails 2 or 3 project.  If you use rmagick or libxml-ruby then pay attention to the installing gems part for some dlls you need to install along with where to get them.

So, having tried various solutions involving fastcgi and url rewrite which I could not get to work on IIS 7.5 under Windows 7 I found http://www.helicontech.com/zoo . I’ve seen the people behind it on various other posts on msdn etc so there is some history of them working on IIS, fastcgi and url rewrite. In fact I think they have had a url rewrite product available for a number of years.

* Install Rails

2) Add http://www.helicontech.com/zoo/feed as a new feed
3) From the zoo tab select Blank Ruby on Rails Rails project and Ruby1.8 and click the install button. It will also install other dependencies.
4) When installing the blank project it will pop up and ask you where to put it along with other required details like the name. Make a note of where the project lives since we need a couple of files from it.
5) From the blank rails project we need the web.config files in the projects root and public directories.  Place these in the same place in your rails project directories.  To use Ruby1.9 we need to replace ruby.1.9.pipe in the web.config in the projects root directory with ruby.1.8.pipe. You may also have to add the path to ruby’s bin directory to your environment variables – C:\Ruby18\bin or C:\Ruby19\bin
6) Ensure that the projects directories are writeable by the IIS_IUSRS user.
7) Add the project to IIS with the project path pointing to the rails projects root directory (not public like you would with a rails project under apache).

* Install Git

This is used for version control and can be found on http://git-scm.com/ Install the version marked ‘Full installer for official Git for Windows 1.7.8′ or similar (version name might be different).

* Install required gems (libxml and imagemagick specific instructions)

There are various 3rd party dependencies that the gems that MethodBox requires including imagemagick (ie. rmagick) and libxml-ruby. On windows this requires a little bit of user intervention during the install process. Go to http://www.imagemagick.org/script/binary-releases.php?ImageMagick=uteqfietdab37ghqrvfuvoul55#windows and download http://www.imagemagick.org/download/binaries/ImageMagick-6.7.3-7-Q16-windows-dll.exe
Double click and go through the installer, selecting to install C and C++ header files and libraries from the additional options page
add environment variable CPATH=\path\to\imagemagick\include and LIBRARY_PATH=\path\to\imagemagick\lib

There is a high chance that the libxml-2.2.dll needed for libxml-ruby is not present in the lib folder and will pop up an error.  The dll can be found in C:\Ruby18\lib\ruby\gems\1.8\gems\libxml-ruby-2.2.0-x86-mingw32\lib\libs\  Copy the libxml, iconv and zlib dlls and put in the C:\Ruby18\bin folder.

Note: If you are not using mysql then comment any mysql gem out of the Gemfile. Otherwise the system may complain about libmysql.dll missing.  If you are using mysql you need to copy the dll from the mysql/bin folder to the ruby lib folder.

* SQL server and rails

1) Find out your SQL server details. If your SQL server instance has not been allowed through the firewall then you need to find out its details: open up the sqlserver management console (which you can install along with sqlserver express via the Web Platform Installer – I recommend this way, downloading on its own and installing does not work correctly) and look at your db details.
2) Set up a Data Source Name (DSN) for your ODBC connection.  This is not that well documented so you need to find the C:\Windows\sysWOW64 directory and start the odbcad32 programme.  Then you add a system DSN for your instance of sqlserver.
3) Set up your rails projects database.yml as normal with the following records:

mode: odbc
dsn: sqlserverapp-dsn (the one you created earlier)
host: localhost (or whatever)

# Ruby, Windows and RMagick

Been doing a lot of rails work on windows recently and ran into some issues that needed solved.  Just like on Unix, to get the RMagick gem working on a windows platform you need to install ImageMagick.  Go to http://www.imagemagick.org/script/binary-releases.php?ImageMagick=uteqfietdab37ghqrvfuvoul55#windows and download http://www.imagemagick.org/download/binaries/ImageMagick-6.7.3-7-Q16-windows-dll.exe

Double click and go through the installer, selecting to install C and C++ header files and libraries from the additional options page (this is very important)

Then add environmant variable CPATH=\path\to\imagemagick\include and LIBRARY_PATH=\path\to\imagemagick\lib

You can then ‘gem install rmagick’ and it will build it using the native image magick libraries.

# Bundler, OSX and the MysqlCompat::MysqlRes error

If you get the uninitialized constant MysqlCompat::MysqlRes error when trying to run your Rails app all the evidence points to it being a 32 v 64 bit issue.  However, I had built mysql for the x86_64 architecture and the mysql gem installed was also for 64 bits.  So why was I still getting this error.  It turns out that bundler was building the mysql gem in 32 bits.  OSX Snow Leopard ships with Ruby in a universal binary containing the ppc, i386 and x86_64 binaries and for whatever reason bundle install was using the 32 bit ruby and re-building everything even though I had the gems already installed in the system in 64 bit mode.  This could be because the user doing the building was 1) unprivileged and 2) using bundle install \--path=vendor.  Maybe bundler was picking the first version of ruby that was appropriate to the platform.  However, doing bundle install \--deployment also had the same issues. I have no idea why it was rebuilding gems that already existed on my system. The way to get round it was to force bundler to build in 64 bits by using env ARCHFLAGS='-arch x86_64' bundle install --path=vendor
Maybe the best idea is not to use the Ruby that ships with OSX and build one appropriate to your environment in the first place.

# Taming the Savage Beast (Forums)

We needed a forum for one of our web projects written in rails and a quick google revealed Savage Beast.  It seemed to fit the bill although needed some css tweeks to co-exist with what we currently have.  However, when clicking on its RSS feed icon it threw an ActionController::Request.relative_url_root method missing error which was fixed by creating the class request_error.rb in initializers with the code below:

class ActionController::Request
def relative_url_root
@@relative_url_root ||= case
when @env["RAILS_RELATIVE_URL_ROOT"]
@env["RAILS_RELATIVE_URL_ROOT"]
when server_software == ‘apache’
@env["SCRIPT_NAME"].to_s.sub(/\/dispatch\.(fcgi|rb|cgi)\$/, ”)
else

end
end
end

Based on bug reported here: http://railsforum.com/viewtopic.php?pid=73991#p73991.

It all seems to work fine now.

# Zipfiles, CSV and UUIDs

MethodBox currently uses a java servlet to create Comma Separated Value (CSV) files inside a zip file.  These are then sent back to the rails application on demand over http.  What we needed was a metadata file to go into the zip file explaining what the CSV files had in them.  It was easiest to use the active records about the CSV columns to get the metadata.

For the zipfile manipulation thanks go to this post and the original rubyzip API.

So, first make the HTTP request:

http = Net::HTTP.new(“localhost”, 10000)

#check that the request was OK
if response.response.class == Net::HTTPOK

#check what the response contains

if response.content_type == ‘application/zip’

#make a new file to hold the zipped data

uuid = UUIDTools::UUID.random_create.to_s

#you might need to install the uuidtools gem

File.makedirs(RAILS_ROOT + “/” + “filestore” + “/” +filename)
uf = File.open(RAILS_ROOT + “/” + “filestore” + “/” + filename  + “/” + uuid+ “.zip”,”w”)

#write the content in the response out to the zip file
uf.write(response.body)
uf.close

After this the metadata is created and written to a string called metadata which can then be added to the zip we just created from the http response.  This next line adds the metadata string to the zip inside a file called metadata.txt.

Zip::ZipFile.open(RAILS_ROOT + “/” + “filestore” + “/” + filename  + “/” + uuid+ “.zip”, Zip::ZipFile::CREATE) {|zip| zip.get_output_stream(“metadata.txt”) { |f| f.puts metadata}}

We can then send the completed file back to the requester

send_file RAILS_ROOT + “/” + “filestore” + “/” + filename  + “/” + uuid+ “.zip”, :filename => “something” + “.zip”, :content_type => @archive.content_type, :disposition => ‘attachment’

I have also been looking at using Ruby to do all the CSV file creation but so far speed is proving to be an issue.  However, I found the following link which mentions several libraries.  I am now looking at using a combination of FasterCSV and CSVScan (also available as a gem).  This enables me to write incredibly complex code like this (don’t you just love ruby’s blocks!):

CSVScan.scan(infile) { |row| line = FCSV.parse(row[0], :col_sep => “\t”); new_row = Array.new; if i==0: variable_hash[key].each {|var| pos.push(line[0].rindex(var))} end; i=i+1; pos.each {|col| val = line[0][col];new_row.push(val)}; csv_arr.push(new_row)}

Yeah, it scared me as well!!  It parses a CSV file for several headers and then pulls out the columns which correspond to these headers and adds them into an array.  In MethodBox these files can have 2000 header (ie columns) and 20000 rows so you can see why speed is important when only pulling out a subset of these.

We can then use FasterCSV to write out the new CSV file:

FasterCSV.open(outfile, “w”) do |csv_file| csv_arr.each {|csv| csv_file << csv} end