Archive for the 'Ruby on Rails' Category

Wirble on Windows

November 12th, 2009 by papillon

Wirble is a set of enhancements for Irb. Wirble enables several items mentioned on the RubyGarden “Irb Tips and Tricks” page, including tab-completion, history, and a built-in ri command, as well as colorized results and a couple other goodies. (source)

1. Install gems:

gem install wirble
gem install win32console

2. Create a new file .irbc in your home directory (where the environment variable USERPROFILE points to, e.g. c:\Documents and Settings\John) and paste the following lines:

require 'rubygems' rescue nil
require 'win32/console/ansi'
ENV['IRB_HISTORY_FILE'] = "C:/.irb_history"
require 'wirble'

Wirble.init
Wirble.colorize

(adjust the path in ENV['IRB_HISTORY_FILE'] accordingly).

3. If the HOME environment variables does not exist yet, add it in the System Properties->Advanced Tab->Environment Variables area and set it to %USERPROFILE%.

Note: ANSI color output has some issues, e.g. not updating the screen correctly after Backspace key has been pressed. Simply comment the “require win32/console/ansi” and “Wirble.colorize” lines if necessary.

Rails and SQL Server Update

November 28th, 2006 by papillon

After a couple of weeks working with Ruby on Rails and SQL Server 2005, certain aspects slowly crystalize:

1. The ADO DB driver (which uses win32ole) does not work on Ruby 1.8.4 and 1.8.5. I can not help but wonder who besides me actually uses Rails and SQL Server 2005 ? It justs segfaults on the very first access. So: Do not use it.

2. The ODBC driver of ActiveRecord 1.14.4 does not like the way the SQLServer Adapter creates the requests of the paginator class (SELECT TOP 20 (SELECT …)). It just stops with an “argument out of range” error.

3. What actually does work is this combination: Ruby 1.8.5 + Rails 1.1.6.5618 (Release Candidate 1 of Rails 1.2), using the ODBC driver. The ODBC connection seems to be preferred over the ADO one, and with the latest changes to the SQL Server Adaptor in ActiveRecord 1.14.4.5618, the argument out of range error is gone as well.

4. Decimal columns seem to work fine now. Prior to the update, I had the problem that “1,5″ always got casted into “1.0″, maybe because the separator is a comma and not a dot in my case.

5. What still does not work: DateTime columns with dates prior to the year that the Ruby Time class accepts, so this change is necessary:

In \ruby\lib\ruby\gems\1.8\gems\activerecord-1.14.4.56.18\
lib\active_record\connection_adapters\sqlserver_adapter.rb around line 105 (cast_to_datetime) and line 116 (string_to_time):

change

return Time.mktime(value.year, value.mon, value.day, value.hour, value.min, value.sec)

to

return DateTime.new(value.year, value.mon, value.day, value.hour, value.min, value.sec)

If the column is a DateTime, ActiveRecord should return a DateTime, IMHO.

Dates like 1754-01-01 14:00:00.000 work with this change. Note: 1753 is the earliest date accepted by SQL Server, and ActiveRecord really should accept it.

6. Since I have to work with a legacy database which uses ISO-8859-1 as encoding, the whole rails application has to use the same. Rails 1.2 seems to default to UTF-8, which e.g. breaks the truncate function when it encounters an Umlaut.

Fix: in environment.rb, add the following lines
...
# Include your application configuration below

# Set multibyte encoding to none.
$KCODE = "NONE"

Bottom line: Update to Rails 1.2 and use the ODBC connection for SQL Server 2005.

Table plurals and primary keys

March 31st, 2006 by papillon

This is how one redefines the table name and primary key column:

class MyTableName < ActiveRecord::Base
  set_table_name 'my_other_table_name'
  set_primary_key 'MyPrimaryKeyColumn'

Umlauts (special characters) and AJAX

March 25th, 2006 by papillon

There are two things that need to be done when you want to (or, in my case, have to) use an ISO character set throughout your application (i.e. database and web pages).

1) Set the character encoding to ISO-8859-1 in the HTTP header. From application.rb:

before_filter :set_charset
def set_charset
  @headers["Content-Type"] = "text/html; charset=ISO-8859-1"
end

(See “Foreign language” characters below)

2) Convert data sent via XMLHTTPREQUEST from UTF-8 to ISO-8859-1

Get the iconv library (instructions) (might already be included with Ruby 1.8.4).
Create a new file charset_conversion.rb in the helpers/ directory:

require 'iconv'
class Hash
  def iconv!(to,from)
    iconv = Iconv.new(to,from)
    perform_iconv!(iconv)
    iconv.close
  end

  def perform_iconv!(iconv)
    each_pair do |key,value|
      case value
        when String
          self[key] = iconv.iconv(value)
        when Hash
          value.perform_iconv!(iconv)
      end
    end
  end
end

Include this file in application_helper.rb:

require 'charset_conversion'

In the action that receives the serialized XML data, add a call to iconv! before using the data:

def update
  params.iconv!("iso-8859-1", "utf-8")
  ..

This is essentially my interpretation of the notes from here: Ajax and Character Sets

Dates before 1970

March 20th, 2006 by papillon

The SQL Server adapter uses the Time class by default to represent datetime columns. This leads to problems when you want to represent dates before the year 1970: You would just get nil values.

I quickly found a similar solution (link lost) (scroll to 11/17/05) on the net and implemented the fix like this in my application_helper.rb file:

# Make the SQL Server Adapter work with dates before 1970
module ActiveRecord
  module ConnectionAdapters
    class ColumnWithIdentity
      def cast_to_time(value)
        return value if value.is_a?(Time)
        time_array = ParseDate.parsedate(value)
        time_array[0] ||= 2000
        time_array[1] ||= 1
        time_array[2] ||= 1
        begin
          Time.send(Base.default_timezone, *time_array)
        rescue
          DateTime.new(time_array[0], time_array[1],
          time_array[2], time_array[3],time_array[4],
          time_array[5]) rescue nil
        end
      end
    end #class ColumnWithIdentity
  end #module ConnectionAdapters
end #module ActiveRecord

This overwrites the standard function of the SQL Server Adapter and returns a DateTime if a normal Time is not enough for the given data.

“Foreign language” characters

March 2nd, 2006 by papillon

The application I am working on is in german, so Rails needs to display Umlauts correctly (e.g. ä,ö,ü). At least with WebBrick, I was not able to convince it to send pages in ISO-8859-1, it always defaulted to UTF-8 which the Browsers would not interprete correctly.

My temporary solution is to overwrite the default codepage like this:

class ApplicationController < ActionController::Base
  before_filter :set_charset
  def set_charset
    @headers["Content-Type"] = "text/html; charset=ISO-8859-1"
  end
end

Using that, the Umlauts appear correctly in all Browsers. Oh well, it works for now…

SQLServer and Paging

March 2nd, 2006 by papillon

Both the standard scaffold generator and my modified version of the AJAX scaffold support paging, i.e. displaying 10 items per page and allowing the user to flip through the pages with the usual first, last, next, previous links.

It does not work out of the box with SQL Server, unfortunately. You have to tell the driver explicitely that it should order the table by your primary key (id). Example:

@header_pages, @headers =
  paginate :headers, :per_page => 10,
  :order => ’id asc’

Rails and SQL Server

March 1st, 2006 by papillon

This page include almost everything you need to get started with SQL Server (2005): HowtoConnectToMicrosoftSQLServer

Basically, you have to copy the file ADO.rb from the latest Ruby-DBI source distribution to the directory

ruby\\lib\\ruby\\site_ruby\\1.8\\DBD\\ADO

and then set up your database.yml like this:

development:
adapter: sqlserver
database: mydb
host: myhost
username: myuser
password: mypassword