If you want to have a Rails application work under a subdirectory, as in http://www.example.com/rails_app , then add this line to your config/environment.rb.
ActionController::AbstractRequest.relative_url_root = "/rails_app"
Tuesday, October 21, 2008
Thursday, October 16, 2008
Using Ruby Java Bindings on Dreamhost
Getting rjb, also known as "Ruby Java Bindings' to work in a Dreamhost account can be somewhat problematic. Fortunately, it is also fairly straightforward. You just have to install all the dependencies in the user directory.
In my case, I was setting up a Rails Application that used the iText Java library to fill in PDF documents for user download. Of course, the server environment was not using Sun Java and the Java headers were not present, so gem install rjb failed. Joy.
The first course of action was to do a local install of Java.
Download jdk-6u7-linux-x64.bin and jre-6u7-linux-x64.bin from the Sun Java site. Then create an ~/opt directory and extract the JRE and JDK (you will need to chmod u+x both files then call them from the command line). Move the resulting folders to ~/opt . I renamed the folders to jdk and jre for simplicity.
Now you ensure that user gems are enabled in cPanel. Then add the following 3 lines to ~/.bash_profile
export JAVA_HOME=/home/username/opt/jdk
export GEM_PATH=/home/username/ruby/gems
export GEM_HOME=/home/username/ruby/gems
Run source ~/.bash_profile to load the paths.
Now you can run gem install rjb without any problems. You will likely have to re-install Rails and other gems because we will be telling our Rails app to load gems from the user directory. Just use the regular gem install syntax.
Add the following 2 lines to your config/environment.rb at the top
ENV['GEM_PATH']='/home/username/ruby/gems'
ENV['JAVA_HOME']='/home/username/opt/jdk'
That's pretty much it.
I will concede that these probably aren't the best instructions, but this is the real meat of the solution. If you keep getting "no such file to load" errors, you will need to extract the gems to the vendor/plugins directory. cd RAILS_ROOT/vendor/plugins and gem unpack gem_name for each problematic gem. I believe this is an issue with Passenger.
Please correct me if I am wrong about any of this, it was a very long day!
In my case, I was setting up a Rails Application that used the iText Java library to fill in PDF documents for user download. Of course, the server environment was not using Sun Java and the Java headers were not present, so gem install rjb failed. Joy.
The first course of action was to do a local install of Java.
Download jdk-6u7-linux-x64.bin and jre-6u7-linux-x64.bin from the Sun Java site. Then create an ~/opt directory and extract the JRE and JDK (you will need to chmod u+x both files then call them from the command line). Move the resulting folders to ~/opt . I renamed the folders to jdk and jre for simplicity.
Now you ensure that user gems are enabled in cPanel. Then add the following 3 lines to ~/.bash_profile
export JAVA_HOME=/home/username/opt/jdk
export GEM_PATH=/home/username/ruby/gems
export GEM_HOME=/home/username/ruby/gems
Run source ~/.bash_profile to load the paths.
Now you can run gem install rjb without any problems. You will likely have to re-install Rails and other gems because we will be telling our Rails app to load gems from the user directory. Just use the regular gem install syntax.
Add the following 2 lines to your config/environment.rb at the top
ENV['GEM_PATH']='/home/username/ruby/gems'
ENV['JAVA_HOME']='/home/username/opt/jdk'
That's pretty much it.
I will concede that these probably aren't the best instructions, but this is the real meat of the solution. If you keep getting "no such file to load" errors, you will need to extract the gems to the vendor/plugins directory. cd RAILS_ROOT/vendor/plugins and gem unpack gem_name for each problematic gem. I believe this is an issue with Passenger.
Please correct me if I am wrong about any of this, it was a very long day!
A big thank-you to the Planet
Thanks for getting hacked, you made my day a whole lot more interesting!
Saturday, September 27, 2008
Problems with IE7 Sessions Not Saved in Rails or PHP
If you are unlucky, your login routine will work in Firefox, Internet Explorer 6, Safari, Opera, or whatever, but it won't persist in Internet Explorer 7. x
I spent days on this one: Login worked great in Firefox, but in IE7 the same credentials resulted in a page that looked like I never attempted to log in. The logs showed me that the user credentials were accepted and the page redirected as expected, but the subsequent page load was absent any sign that I logged in.
Well, check your subdomain. You can't have an underscore in a subdomain. http://support.microsoft.com/kb/909264
In this instance, IE7 is inconsistently supporting standards. The browser will accept a badly formatted domain and show you the page in your browser, but will refuse to set the session cookie. Firefox and Safari are not quite so strict.
I spent days on this one: Login worked great in Firefox, but in IE7 the same credentials resulted in a page that looked like I never attempted to log in. The logs showed me that the user credentials were accepted and the page redirected as expected, but the subsequent page load was absent any sign that I logged in.
Well, check your subdomain. You can't have an underscore in a subdomain. http://support.microsoft.com/kb/909264
In this instance, IE7 is inconsistently supporting standards. The browser will accept a badly formatted domain and show you the page in your browser, but will refuse to set the session cookie. Firefox and Safari are not quite so strict.
Thursday, July 03, 2008
Rails: Get controller route hash from url string
This is somewhat uncommon, but to get the routing hash from a URL string:
ActionController::Routing::Routes.recognize_path('/users/1')
# => {:controller => 'users', :action => 'show', :id => '1' }
ActionController::Routing::Routes.recognize_path('/users/1')
# => {:controller => 'users', :action => 'show', :id => '1' }
Saturday, June 07, 2008
Saturday, May 17, 2008
Using mDNS / Zeroconf / Avahi and Firestarter Firewall on Ubuntu
About Multicast DNS
Multicast DNS (mDNS) allows machines on a local network to connect by name without the need for a local DNS server. Each machine must have a hostname set, and a mDNS client/server installed. Macs have it preinstalled (being called Bonjour), as well as modern releases of Linux including Ubuntu(called avahi). Windows clients can download and install Bonjour for Windows from the Apple website. It seems most modern printers use mDNS for easy printer setup. Even though I run a local DNS server using dnsmasq, mDNS makes DHCP client access easy.
The Problem
Long ago I installed Bonjour for Windows so I could access the machine via mDNS (multicast DNS). Today, my Ubuntu 8.04 machine would no longer connect to my Windows printer share. It turns out that Firestarter on the Ubuntu machine was the culprit. mDNS requests were being blocked regardless of my Firestarter config. So here is the fix:
sudo gedit /etc/firestarter/user-pre
Add the following two lines and save:
$IPT -A INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
These two IP tables rules allow the mDNS requests in and out, and override any GUI configuration in Firestarter.
Restart avahi, then restart firestarter:
sudo /etc/init.d/avahi-daemon restart
sudo /etc/init.d/firestarter restart
If you are still having trouble, look at /etc/default/avahi-daemon and make sure it says: AVAHI_DAEMON_DETECT_LOCAL=1 . Also run sudo netstat -ltunp to verify that avahi-daemon is listening on port 5353.
Found here.
UPDATE: apparently this doesn't work for some.
Multicast DNS (mDNS) allows machines on a local network to connect by name without the need for a local DNS server. Each machine must have a hostname set, and a mDNS client/server installed. Macs have it preinstalled (being called Bonjour), as well as modern releases of Linux including Ubuntu(called avahi). Windows clients can download and install Bonjour for Windows from the Apple website. It seems most modern printers use mDNS for easy printer setup. Even though I run a local DNS server using dnsmasq, mDNS makes DHCP client access easy.
The Problem
Long ago I installed Bonjour for Windows so I could access the machine via mDNS (multicast DNS). Today, my Ubuntu 8.04 machine would no longer connect to my Windows printer share. It turns out that Firestarter on the Ubuntu machine was the culprit. mDNS requests were being blocked regardless of my Firestarter config. So here is the fix:
sudo gedit /etc/firestarter/user-pre
Add the following two lines and save:
$IPT -A INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
These two IP tables rules allow the mDNS requests in and out, and override any GUI configuration in Firestarter.
Restart avahi, then restart firestarter:
sudo /etc/init.d/avahi-daemon restart
sudo /etc/init.d/firestarter restart
If you are still having trouble, look at /etc/default/avahi-daemon and make sure it says: AVAHI_DAEMON_DETECT_LOCAL=1 . Also run sudo netstat -ltunp to verify that avahi-daemon is listening on port 5353.
Found here.
UPDATE: apparently this doesn't work for some.
Tuesday, March 18, 2008
Compile And Install FFMPEG on Redhat RHEL4
I just had the wonderful opportunity to set up a video sharing site on Redhat Enterprise Linux 4. Yeah. Four.
The worst part was getting ffmpeg to work, so here are my notes.
Requirements
(download, extract, etc.)
Configure, Compile, and Install FFMPEG
Create Symlinks
ln -s /usr/local/lib/libavformat.so.50 /usr/lib/libavformat.so.50
ln -s /usr/local/lib/libavcodec.so.51 /usr/lib/libavcodec.so.51
ln -s /usr/local/lib/libavutil.so.49 /usr/lib/libavutil.so.49
ln -s /usr/local/lib/libmp3lame.so.0 /usr/lib/libmp3lame.so.0
ln -s /usr/local/lib/libavformat.so.51 /usr/lib/libavformat.so.51
ln -s /usr/local/lib/libavformat.so.52 /usr/lib/libavformat.so.52
ln -s /usr/local/lib/libavdevice.so.52 /usr/lib/libavdevice.so.52
ln -s /usr/local/lib/libx264.so.58 /usr/lib/libx264.so.58
ln -s /usr/local/lib/libtheora.so.0 /usr/lib/libtheora.so.0
ln -s /usr/local/lib/libfaad.so.0 /usr/lib/libfaad.so.0
ln -s /usr/local/lib/libfaac.so.0 /usr/lib/libfaac.so.0
If you don't create these symlinks you will get errors like:
Run ffmpeg and it should spit out that insane list of options, wihout any errors.
The worst part was getting ffmpeg to work, so here are my notes.
Requirements
(download, extract, etc.)
- faac
- faad2
- lame
- ./configure && make && make install
- libtheora
- ./configure && make && make install
- libvorbis
- ./configure && make && make install
- xvidcore
- cd build/generic; ./configure && make && make install
- x264
- download and install latest subversion
- ./configure --enable-shared && make && make install
Configure, Compile, and Install FFMPEG
./configure --enable-libmp3lame --enable-libvorbis \
--enable-libxvid --enable-shared --enable-libfaac \
--enable-libfaad --enable-gpl --enable-libtheora \
--enable-libx264
make
make install
Create Symlinks
ln -s /usr/local/lib/libavformat.so.50 /usr/lib/libavformat.so.50
ln -s /usr/local/lib/libavcodec.so.51 /usr/lib/libavcodec.so.51
ln -s /usr/local/lib/libavutil.so.49 /usr/lib/libavutil.so.49
ln -s /usr/local/lib/libmp3lame.so.0 /usr/lib/libmp3lame.so.0
ln -s /usr/local/lib/libavformat.so.51 /usr/lib/libavformat.so.51
ln -s /usr/local/lib/libavformat.so.52 /usr/lib/libavformat.so.52
ln -s /usr/local/lib/libavdevice.so.52 /usr/lib/libavdevice.so.52
ln -s /usr/local/lib/libx264.so.58 /usr/lib/libx264.so.58
ln -s /usr/local/lib/libtheora.so.0 /usr/lib/libtheora.so.0
ln -s /usr/local/lib/libfaad.so.0 /usr/lib/libfaad.so.0
ln -s /usr/local/lib/libfaac.so.0 /usr/lib/libfaac.so.0
If you don't create these symlinks you will get errors like:
ffmpeg: error while loading shared libraries: libavdevice.so.52: cannot open shared object fileDone.
Run ffmpeg and it should spit out that insane list of options, wihout any errors.
Saturday, March 01, 2008
Online Flashcards and Quizzer

I just launched a new online flash cards and quizzing site called FB_Quizzr. The site is primarily intended to be used as a Facebook application.
Wednesday, February 27, 2008
How to Disable Asset Timestamps in Rails
By default, Rails appends a timestamp parameter to asset urls to aid in cache management. If you need to disable this, simply add the following line to your config/environment.rb
ENV['RAILS_ASSET_ID'] = ''
ENV['RAILS_ASSET_ID'] = ''
Tuesday, February 26, 2008
Advanced puts Syntax in Ruby
The "puts" command can be used with sprintf syntax using the percent (%) sign as follows:
puts "ABC %2.2f" % 3.567
=> "ABC 3.57"
puts "ABC %2.2f DEF %5s" % [3.567, "abcd"]
=> "ABC 3.57 DEF abcd"
puts "ABC %2.2f" % 3.567
=> "ABC 3.57"
puts "ABC %2.2f DEF %5s" % [3.567, "abcd"]
=> "ABC 3.57 DEF abcd"
Saturday, February 16, 2008
Load Balance Rails Mongrel Clusters With Apache
A simple solution for load balancing a Ruby on Rails Mongrel cluster with an Apache front end is to use the randomizing feature in Apache module mod_apache’s rewrite map feature. Say, for instance, you have 3 Mongrel servers, running on ports 4000 to 4002 on localhost. First create a file map.txt containing these numbers:
ports 4000|4001|4002
Then ensure the following directives are present inside the VirtualHost stanza in your Apache configuration:
ProxyRequests Off
ProxyPassReverse / http://localhost:4000/
ProxyPassReverse / http://localhost:4001/
ProxyPassReverse / http://localhost:4002/
ProxyPreserveHost On
RewriteEngine On
RewriteMap servers rnd:/path/to/your/map.txt
RewriteRule ^/(images|stylesheets|javascripts)/?(.*) $0 [L]
RewriteRule ^/(.*)$ http://localhost:${servers:ports}/$1 [P,L]
Restart Apache, and that is it.
I have had great success using both the Pound load balancer, and Nginx, which I suggest highly, but Apache does a great job when necessary.
ports 4000|4001|4002
Then ensure the following directives are present inside the VirtualHost stanza in your Apache configuration:
ProxyRequests Off
ProxyPassReverse / http://localhost:4000/
ProxyPassReverse / http://localhost:4001/
ProxyPassReverse / http://localhost:4002/
ProxyPreserveHost On
RewriteEngine On
RewriteMap servers rnd:/path/to/your/map.txt
RewriteRule ^/(images|stylesheets|javascripts)/?(.*) $0 [L]
RewriteRule ^/(.*)$ http://localhost:${servers:ports}/$1 [P,L]
Restart Apache, and that is it.
I have had great success using both the Pound load balancer, and Nginx, which I suggest highly, but Apache does a great job when necessary.
Wednesday, February 13, 2008
Using :db_file with attachment_fu
The README for attachment_fu says that accessing data using the :db_file backend is outside the scope of the document. Well here is my take on it. You will also need the "mimetype_fu" plugin. Follow the instructions with attachment_fu as usual, and do the following.
Assuming that your attachment model is called "Asset" add the following line to "config/routes.rb":
map.asset_data '/asset/:id', :controller => 'assets', :action => 'show'
Create an AssetController containing at least the following:
(The thumbnail of the original image is found if necessary, and mimetype_fu is used to determine the mime-type sent to the browser)
So now you may use the helper in your views (i.e.):
Assuming that your attachment model is called "Asset" add the following line to "config/routes.rb":
map.asset_data '/asset/:id', :controller => 'assets', :action => 'show'
Create an AssetController containing at least the following:
(The thumbnail of the original image is found if necessary, and mimetype_fu is used to determine the mime-type sent to the browser)
class AssetsController < ApplicationControllerAdd this method to app/helpers/application_helper.rb
def show
asset = Asset.find(params[:id])
if params[:thumbnail]
data = asset.thumbnails.find_by_thumbnail(params[:thumbnail])
end
data ||= asset
send_data (data.db_file.data,
:filename => data.filename,
:type => File.mime_type?(data.filename),
:disposition => 'inline')
end
end
def assetpath(asset,thumb=nil)
"#{asset_data_url(:id => asset.id)}#{thumb.nil? ? '' : "?thumbnail=#{thumb.to_s}"}"
end
So now you may use the helper in your views (i.e.):
<%= image_tag(assetpath(asset_model_instance)) %>
<%= image_tag(assetpath(asset_model_instance,:thumb)) %>
Friday, December 14, 2007
URLs With file_column
This patch modifies the Rails file_column plugin so that it may download a remote file via HTTP in addition to using uploaded data. Now you can specify a string with a full valid URL.
Run it against lib/file_column.rb
Enjoy! file_column patch.
Run it against lib/file_column.rb
Enjoy! file_column patch.
Thursday, December 13, 2007
Rails 2.0 Screencast
He goes a bit fast:
http://www.akitaonrails.com/2007/12/10/the-first-rails-2-0-screencast-english
Direct links to the text versions:
http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial
http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial-part-2
http://www.akitaonrails.com/2007/12/10/the-first-rails-2-0-screencast-english
Direct links to the text versions:
http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial
http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial-part-2
Getting Rails 2.0 Running
So, Rails 2.0 has finally been released. It was a bit of a pain getting all my Ruby Gems updated for some reason. Please keep in mind that the MySQL path is specific to OSX 10.5.
$ sudo gem update sources
$ sudo gem update --system
$ sudo gem uninstall mysql
$ sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
$ sudo gem update -- --with-mysql-dir=/usr/local/mysql
$ sudo gem install rails --include-dependencies
I know there is a bit of duplicated effort there, but I had issues with that MySQL gem.
Finally Rails 2.0 joy. Now to fiddle around with it before starting a new project...
$ sudo gem update sources
$ sudo gem update --system
$ sudo gem uninstall mysql
$ sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
$ sudo gem update -- --with-mysql-dir=/usr/local/mysql
$ sudo gem install rails --include-dependencies
I know there is a bit of duplicated effort there, but I had issues with that MySQL gem.
Finally Rails 2.0 joy. Now to fiddle around with it before starting a new project...
Installing the MySQL Ruby Gem for Rails MySQL Support on OSX Leopard
Some special command line magic is required to install the MySQL Gem on OSX Leopard (10.5).
$ export ARCHFLAGS="-arch i386"
$ sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
I got this information from http://trac.macosforge.org/projects/ruby/wiki/Troubleshooting.
$ export ARCHFLAGS="-arch i386"
$ sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
I got this information from http://trac.macosforge.org/projects/ruby/wiki/Troubleshooting.
Wednesday, December 05, 2007
Netbeans 6 Final
Finally released! There's not many pieces of software I will actually use in beta, but. Wow. Amazing IDE here. I wish there had been nice open source IDE's like this back in the day.
Wednesday, November 21, 2007
Rails SQL Optimization
In order to automate the optimization of SQL queries in Ruby on Rails, I wrote this script to parse the output of the logs. It finds all the unique SQL queries made by different controllers, and runs an SQL EXPLAIN for each. This is really good for finding missing indexes and large table scans.
I have only tested this on Mac/MySQL, so your mileage may vary (it uses *NIX file paths). This script has saved me MUCH time. Of course, when optimizing queries, don't go overboard on eager loading. ActiveRecord eager loading can be slow if you use multiple nested includes.
Just run this script within your Rails application root directory, and it will create a file named explained.html. You may set the RAILS_ENV environment variable to specify production mode. The script automatically loads your database configuration from log/database.yml
Oh, and there needs to be at least 2 pageloads in your log. I haven't bothered fixing this bug.
So here is the script.
UPDATE: I came across some good tips for additional optimization here.
I have only tested this on Mac/MySQL, so your mileage may vary (it uses *NIX file paths). This script has saved me MUCH time. Of course, when optimizing queries, don't go overboard on eager loading. ActiveRecord eager loading can be slow if you use multiple nested includes.
Just run this script within your Rails application root directory, and it will create a file named explained.html. You may set the RAILS_ENV environment variable to specify production mode. The script automatically loads your database configuration from log/database.yml
Oh, and there needs to be at least 2 pageloads in your log. I haven't bothered fixing this bug.
So here is the script.
UPDATE: I came across some good tips for additional optimization here.
Subscribe to:
Posts (Atom)