Running Ruby on Rails 3.1 on FreeBSD

Are you trying to install / run Rails 3.1 on a FreeBSD system...?
You will probably get errors of a missing javascript engine.

You should try to install node and google V8 as javascript engine

cd /usr/ports/lang/v8
make install clean
cd /usr/ports/www/node
make install clean

Now it should work :-)

Installing Ruby on Rails with Mysql on Windows

No I don't like working on Windows, but unfortunately my co-workers haven't seen the light yet.

To make the rails setup a bit easier I needed to document the installation of Ruby on Rails on Windows with a Mysql database.
The description is about Ruby 1.9.?, Rails 3.0, Mysql 5.5 with the mysql2 gem.. and a lot of gems that got installed and compiled via "bundle install"

Here's a raw extract of the document I build:

1. Install MySQL

In our situation MySQL was installed. But you should install MySQL with development files. (C++ headers and Libraries).
Just download the Community Server at http://mysql.com/.

2. Install Ruby

Install the base Ruby version. Download the installer at http://rubyinstaller.org/
Run the installer and check the following items:

  • Add Ruby executables to your PATH
  • Associate .rb and .rbw files with this Ruby Installation

3. Install DevKit

Because a lot of Ruby plugins make use of Native extensions you need a compiler. For windows there's devkit to the rescue. Download it at rubyinstaller: http://rubyinstaller.org/.

Extract this to (for example) c:/devkit (this text assumes this location)
Open a command prompt: (cmd.exe) and enter the following commands.

cd c:/devkit 
ruby dk.rb init

DevKit wil probably find your ruby installation. But to make sure check the file c:/devkit/config.yml. It should contain the path of your Ruby installation:

--- 
- C:/Ruby192

This step installs (or updates) an operating_system.rb file into the relevant directory needed to implement a RubyGems pre_install hook and a devkit.rb helper library file into \lib\ruby\site_ruby. NOTE: you may need to use the –force option to update (with backup of the originals) the above mentioned files as discussed at the SFX DevKit upgrade FAQ entry.

Test the Devkit installation Confirm your Ruby environment is correctly using the DevKit by running.

gem install rdiscount --platform=ruby

RDiscount should install correctly and you should see:

Temporarily enhancing PATH to include DevKit... in the screen messages.

After this double check if it works by running:

ruby -rubygems -e "require 'rdiscount'; puts RDiscount.new('**Hello RubyInstaller**').to_html" 

to confirm that the rdiscount gem is working. (This should generate HTML)
(More info: https://github.com/oneclick/rubyinstaller/wiki/Development-Kit )

4. Install Git

If you not already have installed git, please do it. You will like it!
Git is required for many plugins so you need it.

  • download git at http://code.google.com/p/msysgit/ (choose a version I don't know :P, the latest .exe ?? )
  • execute the installer, select the following options:
    • check “Run Git and included tools from the windows command prompt” (Select the option with the red letters that scream "don't pick me" :P )
    • checkout-as-is and commit-as-it.

5. Install Rails with the mysql2 plugin

Next install Ruby on Rails. (We don't install/generate the docs)

gem install rails --no-ri --no-rdoc

6. Install the mysql2 gem

To build mysql2 support do this: (Point the paths to your MySQL install directory!)

NOTE: When using a 64bit version of windows you probably run into issues. Thanks for mentioning Luis! (Read more about it: http://blog.mmediasys.com/2011/07/07/installing-mysql-on-windows-7-x64-and-using-ruby-with-it/ ).

gem install mysql2 -- '--with-mysql-lib="c:\Program Files\MySQL\MySQL Server 5.5\lib" --with-mysql-include="c:\Program Files\MySQL\MySQL Server 5.5\include"'

(Mysql5.1 seems to have the path: c:\Program Files\MySQL\MySQL Server 5.1\lib\opt)

Fix up Bundler (the gem management tool) to know what the mysql2 gem build settings need to be..
Else you're "bundle install" will fail when installing or updating the mysql2 gem!!

bundle config build.mysql2 '--with-mysql-lib="c:\Program Files\MySQL\MySQL Server 5.5\lib" --with-mysql-include="c:\Program Files\MySQL\MySQL Server 5.5\include"'

As soon as you start using this installation you could get errors like 'libmysql.dll not found.
To solve this copy this file from the mysql-installation/lib directory to the ruby/bin directory.

Slightly Unrelated, install the Rails app

Pull the rails app from git. (Or copy it). And run bundler install to install all gems..

cd /rails/app
bundle install 

I've recieved the following error when doing this:

Resolving deltas: 100% (3434/3434), done.
Checking out files: 100% (85/85), done.
Fetching source index for http://rubygems.org/

Could not find devise-1.4.0 in any of the sources

I seems that devise was updated and the specific version in Gemfile.lock wasn't available anymore.
You can Force the installation of this updated package

bundle update devise

These were my steps to build a working rails environment under windows...
Enough of windows, Now back to my Mac :P

ActiveSupport Option Hashes

A small blog item, for remembering this method...

When using a (normal) Hash in Ruby on Rails accessing an element with a symbol key or string key results in a different item.

Example
(Notice the use of a string and symbol to access a key)

normal = {'foo'=>"lish"} 
normal[:foo] = 'bar'

results in the hash:

{"foo"=>"lish", :foo=>"bar"}

To solve this issue you can convert every Hash to HashWithInDifferentAccess

special = {'foo'=>'lish'}.with_indifferent_access
special[:foo] = 'bar'

Results in

{"foo"=>"bar"}
special.class => ActiveSupport::HashWithIndifferentAccess

that more like it :-)

Production gotcha: Rails send_file seems to corrupt files

What's wrong with the following Rails code?

class ResourceController < ApplicationController  
  DEFAULT_OPTIONS = { :disposition => 'inline' }

  def send_file1
    send_file 'flash1.swf', DEFAULT_OPTIONS
  end

  def send_file2
    send_file 'flash2.swf', DEFAULT_OPTIONS
  end
end

This code works perfectly in development mode. In production mode retrieving the two different files the second file gets corrupt / wrong...

After a long search I looked in the rails code:

  def send_file(path, options = {}) #:doc:
    raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
 
    options[:length]   ||= File.size(path)
    options[:filename] ||= File.basename(path) unless options[:url_based_filename] 
    send_file_headers! options  
    #.... 
  end

OOops... the send_file code modifies my class constant!
And after the first call the length and filename is placed in the class constant...
This is no problem in development mode because the classes are reloaded every time. In production mode every mongrel server has it's own instance...

“2008-03-30”.to_date.to_time.tomorrow == “2008-03-30”

I wrote a very nice routine which would iterate over a few days.
Today I found my loop never ending !?! And this is very scary because the routine is a background process that needs to iterate over the last x-days.

But there's a problem when you're living in The Netherlands and you have to use daylight savings.

Try this code:


>> "2008-03-30".to_date.to_time.tomorrow.to_date
=> Sun Mar 30

WTF !! 2008-03-30 => Tomorrow => 30 March 2008 ?!?

I indeed complained, that time was passing so quickly. But I didn't mean to keep it stuck at 30 March!
Oh.. I'ts only my Rails Application...

How's this possible?

>> "2008-03-30".to_date.to_time.tomorrow
=> Sun Mar 30 23:00:00 +0200 2008

At 30-03-2008 the clock has been set back for daylight savings. Well I assume rails simply adds 24 hours with the method tomorrow. And yesterday we had 25 hours.

More info about this bug: http://dev.rubyonrails.org/ticket/2353

My temporary solution is to add some hours to tomorrow.


>> tomorrow_time = "2008-03-30".to_date.to_time.tomorrow + 12*60*60
=> Mon Mar 31 11:00:00 +0200 2008
>> tomorrow_time.to_date
=> Mon, 31 Mar 2008

Sometimes I hate Ruby on Rails!

why don't we collectively protest agianst the oppression of daylight saving time?
Well Tijn, I agree!