středa 23. ledna 2008

ar_fixture: BigDecimal and YAML problem

When we used ar_fixture plugin, we found bug with BigDecimal. When we called Amount.to_fixture, this record was generated:

amount_03246:
deleted_at:
id: 3246
value: !ruby/object:BigDecimal {}
currency: 203


classic to_yaml on Amount class works fine. So I think that problem was violated by merging hash or some other magic ;-) in to_fixture method

Solution is easy (similiar as BigDecimal and YAML don't get along): in ar_fixture.rb override BigDecimal.to_yaml method like this:

class BigDecimal
alias :_original_to_yaml :to_yaml
def to_yaml (opts={},&block)
to_s.to_yaml(opts,&block)
end
end

Removing diacritic (windows 1250) in Ruby

We received data in windows 1250 (cp1250) encoding. It's problem in Rails that works with utf8.
When you save these data in YAML, you will get accented signs as \xe1 for á (in cp1250), but strange sign in UTF8. So we need remove this encoding and replace it by ASCII signs.

You can use following code for removing diacritic:

TABLE1250 = {"e1" => "a", "e4" => "a", "e8" => "c", "ef" => "d", "e9" => "e", "ec" => "e", "ed" => "i", "be" => "l", "e5" => "l", "f2" => "n", "f3" => "o", "f6" => "o", "f5" => "o", "f4" => "o", "f8" => "r", "e0" => "r", "9a" => "s", "9d" => "t", "fa" => "u", "f9" => "u", "fc" => "u", "fb" => "u", "fd" => "y", "9e" => "z", "c1" => "A", "c4" => "A", "c8" => "C", "cf" => "D", "c9" => "E", "cc" => "E", "cd" => "I", "bc" => "L", "c5" => "L", "d2" => "N", "d3" => "O", "d6" => "O", "d5" => "O", "d4" => "O", "d8" => "R", "c0" => "R", "8a" => "S", "8d" => "T", "da" => "U", "d9" => "U", "dc" => "U", "db" => "U", "dd" => "Y", "8e" => "Z"}

def remove_diacritic str
while !str.index("\\x").nil?
idx = str.index("\\x")
str[idx, 4] = "#{TABLE1250[str[idx+2, 2].downcase]}"
end
str
end

úterý 22. ledna 2008

ar_fixture: Database to YAML

We faced problem with storing data from our application to fixtures that we want use to testing.
I found perfect plugin ar_fixtures, but installation process described on official page was broken. Maybe it could be caused by our proxy etc. So better solution is to install this plugin from gems.

This plugin allows download all data in one table to fixture (yaml file with "serialization" of each item).

We need some updates:
1.) select records that fulfil specific conditions
we change original method to_fixture

def to_fixture(limit=nil)
opts = {}
opts[:limit] = limit if limit

by new

def to_fixture(opts = {}, limit=nil)
opts[:limit] = limit if limit

and now, you can use e.g. Amount.to_fixture({:conditions => "value > 500"}) for saving amounts greater than 500 to YAML file

2.) remove bad diacritic from data (see tommorow's post)

3.) export all data
I created this simple method that loads all table names and call to_fixture method over all entity classes

def export_all
tables = ActiveRecord::Base.find_by_sql "select TABLE_NAME as name from INFORMATION_SCHEMA.TABLES"

tables.each do |t|
begin
className = t.name.classify
eval(className).to_fixture
puts "#{className} done"
rescue
puts "#{t.name} is not Entity class" # any relation
end
end
end