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