Ever wondered whether you could turn that Ruby on Rails app you wrote into a executable program? Well, wonder no more!
Using SQLite and only a couple of Ruby scripts, turning any Rails app into a standalone executable file that can be installed on any machine without any extra software is quite painless. Here's everything you'll need to get your app packaged up for all those poor folks without Rails:
After a bit of fiddling, I was able to get an app of my own into a packaged executable file. My one concern at the time was keeping the SQLite database from resetting itself back to its original state. This is a concern that Erik lays out in his tutorial and is now most likely a moot point. However, at the time of trying this out for myself (back in February) I remembered having some trouble. Below is the logic and code I used inside of init.rb to get by this issue.
To maintain the database, I would look for its filename first in a folder named 'db' relative to the location that the executable file was. For example, "C:\db\" if the executable was in "C:\". If the database was there, then great - I was done. If the database file was not there, then most likely it was deleted or this was the first time the program was being run. I would then check the temporary location that the database file resided in, referenced via newlocation(), and if I found it, I would then copy it to the folder I had originally sought it. In my example, "C:\db\".
Afterwards, (getting a little fancy I suppose) I would launch either Firefox or Internet Explorer using a browser.rb script that I had placed in the same folder as init.rb - though modified, the base source of browser.rb I found online but regretfully can't remember where. The browser would launch an .html file (also in the same folder) that would have a redirect script coded into it - that would then after a specified period of time (I had it wait 50 seconds on a very slow Compaq Windows 2000 pc) point the broswer to http://localhost:3000. Thus, all the user had to do was double click on the program file and wait for the page to load. I should note that this assumed that the user had installed Firefox/IE in the default directory.
Below is the code I used in the init.rb file and the browser.rb file.
init.rb
require 'browser'
require 'ftools'
if defined?(TAR2RUBYSCRIPT)
$url = 'index.html'
$filepath = 'db/somedb.db'
$stderr.puts ".tar2rubyscript is defined..."
if File.exist?(oldlocation($filepath))
$stderr.puts "..somedb.db exists..."
else
$stderr.puts "..somedb.db does not exist..."
if File.exist?(newlocation($filepath))
$stderr.puts "...located somedb.db, copying now..."
$stderr.puts oldlocation()
$stderr.puts oldlocation($filepath)
File.makedirs oldlocation()+'/db'
f = File.new(oldlocation()+'/db/somedb.db', "w+")
File.copy(newlocation($filepath),oldlocation($filepath))
else
$stderr.puts "...could not locate somedb.db..."
end
end
$stderr.puts "....calling #{$url}"
Browser.new( 'FF' ).get( $url )
else
$stderr.puts ".tar2rubyscript is not defined..."
end
at_exit do
require "irb"
require "drb/acl"
require "sqlite3"
end
load "script/server"
browser.rb
class Browser
DEFAULT = 'FF'
IE = 'IE'
FF = 'FF'
@@exe = Hash.new( 'explorer')
@@exe['IE'] = 'explorer'
@@exe['FF'] = 'C:\Program Files\Mozilla Firefox\firefox.exe'
def initialize( browser_name = Browser::DEFAULT )
@broswser = browser_name
@b_exe = select_exe( browser_name )
$stderr.puts( "Using broswer #@broswser ")
end
def get( url )
$stderr.puts( "get is using #@b_exe" )
a = Thread.new( url ){ |t| `call "#{@b_exe}" "#{url}"` }
a.terminate
end
def select_exe( bname )
@@exe[ bname ]
end
def self.get( url,
browser_name = ( @broswser ? @broswser : Browser::DEFAULT ) )
exe = Browser.new(browser_name).select_exe( browser_name )
a = Thread.new( url ){ |t| `start "#{exe}" "#{url}"` }
end
end
I am not very experienced with Ruby, so I have a sneaking suspicion that there's a much better way of doing this. But hey, at least it worked :P
Comments