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 1 class FixYamlEncoding < ActiveRecord::Migration
2 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 12 end
11 13  
12 14 def self.down
... ... @@ -16,15 +18,34 @@ class FixYamlEncoding &lt; ActiveRecord::Migration
16 18 private
17 19  
18 20 def self.fix_encoding(model, param)
19   - result = model.find(:all, :conditions => "#{param} LIKE '%!binary%'")
  21 + result = model.all
20 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 37 end
23 38  
24 39 def self.deep_fix(hash)
25 40 hash.each do |value|
26   - value.force_encoding('UTF-8') if value.is_a?(String) && !value.frozen? && value.encoding == Encoding::ASCII_8BIT
27 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 49 end
29 50 end
30 51  
... ...