Distributing Rails Applications, with migrations
Creating a executable file (.exe for windows for example) from a Ruby on Rails application isn’t something really new. There enough informations about that on the net, the best one can be found here.
Well, then why am I writing this blog? Well the manual from Erik Veenstra ist quite good, but what I didn’t find there anywhere was how to get the migrations done! I want to be able to give this .exe file to someone (or actually I was forced to do it this way) and they should be able to use the application, but when you keep updates in mind then you must have some way to also get migrations working.
I will be repeating some steps that are already mentioned in the “Distributing Rails Applications” tutorial.
First add this to the top of your environment.rb, this is a bit different then mentioned in the tutorial. Basically it should be working as mentioned in the tutorial, but in the last two days I was trying to solve this problem until late in the night and can’t really remember why I changed it
module Rails class Configuration def database_configuration conf = YAML::load(ERB.new(IO.read(database_configuration_file)).result) if defined?(TAR2RUBYSCRIPT) conf.each do |k, v| if v["adapter"] =~ /^sqlite3/ v["database"] = oldlocation(v["database"]) if v.include?("database") v["dbfile"] = oldlocation(v["dbfile"]) if v.include?("dbfile") end end else YAML::load(ERB.new(IO.read(database_configuration_file)).result) end end end end
Create a init.rn in the root of your application folder, you can remove the three “puts” lines, just added them for debug purposes.
at_exit do require "irb" require "drb/acl" require "sqlite3" end puts "Running as an RBA." if defined?(TAR2RUBYSCRIPT) puts "Runing from: " + oldlocation puts "Runing in: " + newlocation load "mig.rb" load "script/server"
As you can see there is a new “load” line which load mig.rb before starting the server. Here is where the magic happens.
Actually the mig.rb is nothing but a copy of the rake script with a extra line.
require 'rubygems' require 'rake' version = ">= 0" ARGV<<"db:migrate" gem 'rake', version load 'rake'
So what happens is that tar2rubyscript executes init.rb on startup, then the mig.rb is called which always does a rake db:migrate. This is done but manually adding “db:migrate” to ARGV, this has to be done so the script can be started with “load”, starting the script with a system command won’t work!
This is because the environment set up by tar2rubyscript will be missing and your migrations just won’t work.
Thats all! Incredible that for this answer I spend 2 long long nights. But now it works as it should, when starting it without tar2rubyscript it work’s as usual and with tar2rubyscript it works also great and I can have migrations when I send out new software versions.
The idea is that the same application is intended to run in two different environments, one being a usual ruby on rails environment on Linux with a MySQL Database and the other being sent out via CD and it must run on windows.
I could have made complete installer to install Ruby, Rubygems, SQLite, the Gems I need … and much more. This way it is much much easier and nobody has to install anything, just click the exe, open the browser and start working.



