Commit 0acccc162c1755c441687ebcb6f259260a01458b

Authored by Braulio Bhavamitra
1 parent 906f3005

Fix yaml migration

Showing 1 changed file with 31 additions and 10 deletions   Show diff stats
db/migrate/20140724134601_fix_yaml_encoding.rb
1 class FixYamlEncoding < ActiveRecord::Migration 1 class FixYamlEncoding < ActiveRecord::Migration
2 def self.up 2 def self.up
3 - fix_encoding(Block, 'settings')  
4 - fix_encoding(Product, 'data')  
5 - fix_encoding(Environment, 'settings')  
6 - fix_encoding(Profile, 'data')  
7 - fix_encoding(ActionTracker::Record, 'params')  
8 - fix_encoding(Article, 'setting')  
9 - fix_encoding(Task, 'data') 3 + ActiveRecord::Base.transaction do
  4 + fix_encoding(Environment, 'settings')
  5 + fix_encoding(Profile, 'data')
  6 + fix_encoding(Product, 'data')
  7 + fix_encoding(ActionTracker::Record, 'params')
  8 + fix_encoding(Article, 'setting')
  9 + fix_encoding(Task, 'data')
  10 + fix_encoding(Block, 'settings')
  11 + end
10 end 12 end
11 13
12 def self.down 14 def self.down
@@ -16,15 +18,34 @@ class FixYamlEncoding &lt; ActiveRecord::Migration @@ -16,15 +18,34 @@ class FixYamlEncoding &lt; ActiveRecord::Migration
16 private 18 private
17 19
18 def self.fix_encoding(model, param) 20 def self.fix_encoding(model, param)
19 - result = model.find(:all, :conditions => "#{param} LIKE '%!binary%'") 21 + result = model.all
20 puts "Fixing #{result.count} rows of #{model} (#{param})" 22 puts "Fixing #{result.count} rows of #{model} (#{param})"
21 - result.each {|r| r.update_column(param, deep_fix(r.send(param)).to_yaml)} 23 + result.each do |r|
  24 + begin
  25 + yaml = r.send(param)
  26 + # if deserialization failed then a string is returned
  27 + if yaml.is_a? String
  28 + yaml.gsub! ': `', ': '
  29 + yaml = YAML.load yaml
  30 + end
  31 + r.update_column param, deep_fix(yaml).to_yaml
  32 + rescue => e
  33 + puts "FAILED #{r.inspect}"
  34 + puts e.message
  35 + end
  36 + end
22 end 37 end
23 38
24 def self.deep_fix(hash) 39 def self.deep_fix(hash)
25 hash.each do |value| 40 hash.each do |value|
26 - value.force_encoding('UTF-8') if value.is_a?(String) && !value.frozen? && value.encoding == Encoding::ASCII_8BIT  
27 deep_fix(value) if value.respond_to?(:each) 41 deep_fix(value) if value.respond_to?(:each)
  42 + if value.is_a? String and not value.frozen?
  43 + if value.encoding == Encoding::ASCII_8BIT
  44 + value.force_encoding "utf-8"
  45 + else
  46 + value.encode!("iso-8859-1").force_encoding("utf-8")
  47 + end
  48 + end
28 end 49 end
29 end 50 end
30 51