Десериализация столбца в базе данных в Rails - PullRequest
0 голосов
/ 04 февраля 2019

В моей базе данных есть испорченный столбец (я использую Postgres).Столбец в базе данных имеет тип jsonb и был сериализован как массив.Я не знаю, как это произошло, но мне нужно все не сериализовать и сохранить существующую информацию в виде массива JSON.

Я пытался найти существующие ответы, но, похоже, ни у кого не было точной проблемы.Кроме того, в предыдущих версиях rails был метод 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: [],
  },
]

1 Ответ

0 голосов
/ 04 февраля 2019

Обновленный ответ

Вы можете использовать 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, чтобы разбить сохраненную строку на хэши, а затем выполнить итерацию этих сопоставлений для соответствующих им хешей.

Дайте мне знать, как вы справляетесь с этим или, если у вас есть какие-либо вопросы - надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...