在Rails的数据库反序列化的列

问题描述 投票:3回答:1

我在数据库中有一个搞砸栏(我使用Postgres的)。在数据库中的列是jsonb类型的,并且它被序列化为数组。我不知道这是怎么发生的,但我需要反序列化的一切并存储现有的信息作为JSON的数组。

我试图寻找答案存在的,但似乎没有人有确切的问题。此外,还有用于在轨道的早期版本unserialize_attribue方法,但它是不存在了对Rails 5.2。

# orders.rb
serialize :content, Array

保存在列中的数据看起来是这样的:

"---\n- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\n  id: 21\n   title: Salade César\n  price: 10\n  tax_rate: '0.0'\n  quantity: 1\n  options: []\n- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\n  id: 22\n  title: Steak\n  price: 14\n  tax_rate: '0.0'\n  quantity: 1\n  options: []\n"

我想目前的数据转换成一个良好的醇” JSON。就像是:

[
  {
    id: 21,
    title: "Salade César",
    price: 1, 
    tax_rate: '0.0',
    quantity: 1,
    options: [],
  },
  {
    id: 22,
    title: "Steak",
    price: 14, 
    tax_rate: '0.0',
    quantity: 1,
    options: [],
  },
]
ruby-on-rails ruby postgresql
1个回答
2
投票

更新答案

您可以使用YAML.parse对于这一点,那么它的内置to_ruby方法:

str = "---\n- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\n  id: 21\n  title: Salade César\n  price: 10\n  tax_rate: '0.0'\n  quantity: 1\n  options: []\n- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\n  id: 22\n  title: Steak\n  price: 14\n  tax_rate: '0.0'\n  quantity: 1\n  options: []\n"

YAML.parse(str).to_ruby
# => [{"id"=>21, "title"=>"Salade César", "price"=>10, "tax_rate"=>"0.0", "quantity"=>1, "options"=>[]}, {"id"=>22, "title"=>"Steak", "price"=>14, "tax_rate"=>"0.0", "quantity"=>1, "options"=>[]}]

YAML.parse(str).to_ruby.to_json
# => "[{\"id\":21,\"title\":\"Salade C\\u00e9sar\",\"price\":10,\"tax_rate\":\"0.0\",\"quantity\":1,\"options\":[]},{\"id\":22,\"title\":\"Steak\",\"price\":14,\"tax_rate\":\"0.0\",\"quantity\":1,\"options\":[]}]"

注:你在提问字符串无效YAML,这意味着这是行不通的,首先,与如下:)这样的答案


原来的答案

内置的解析器不工作这一点,所以这里有一个简单的Ruby的解决方案:

str = "---\n- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\n  id: 21\n   title: Salade César\n  price: 10\n  tax_rate: '0.0'\n  quantity: 1\n  options: []\n- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\n  id: 22\n  title: Steak\n  price: 14\n  tax_rate: '0.0'\n  quantity: 1\n  options: []\n"

DELIMITER = "!ruby/hash:ActiveSupport::HashWithIndifferentAccess".freeze

str.split(DELIMITER).each_with_object([]) do |yaml_hash, array| 
  hash = yaml_hash.lines.each_with_object({}) do |line, hash|
    stripped_line = line.chomp.delete(' ')
    k, v = stripped_line.split(':')
    hash[k] = v if k && v
  end

  array << hash unless hash.empty?
end.to_json

基本上,您使用的序列化!ruby/hash:ActiveSupport::HashWithIndifferentAccess到存储字符串分割成哈希值,然后通过这些映射到它们各自的哈希值进行迭代。

让我知道你是怎么得到这个,或者如果您有任何问题 - 希望它帮助。

© www.soinside.com 2019 - 2024. All rights reserved.