Символизировать ключи в полях MySQL JSON, используя ActiveRecord - PullRequest
0 голосов
/ 15 февраля 2019

У меня есть столбец JSON в одной из моих моделей, который содержит массив хэшей

  create_table "articles", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.string "title"
    t.json "data"
  end

Когда я храню хэш Ruby внутри #data, ActiveRecords заботится о преобразовании его в json и храненииэто в БД.

article = Article.new(data: [{ some: "data" }])
article.save
article.reload.data
=> [{ "some" => "data" }]

Но, как вы можете видеть в примере выше, когда я читаю поле обратно из БД, ключи преобразуются в строки (это очевидно, потому что он хранится в формате JSON).

Мой вопрос: обеспечивает ли ActiveRecord какую-либо встроенную функциональность для преобразования строковых ключей в символы?

Я мог бы перезаписать получательи символизируют ключи на месте, но это становится неудобным, если у вас много полей json:

def data
  _data = self[:data]
  _data.each.with_index do |hash, idx|
    _data[idx] = hash.symbolize_keys
  end
  _data
end

Это становится более беспорядочным, когда вы смешиваете типы данных внутри одного массива, и вы должны позаботиться о том,хеш это или нет ...

# this would fail because String does not implement #symbolize_keys
article.data << "foo"
article.data << { bar: "test" }

1 Ответ

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

Существует способ преобразовать строковые ключи в символы, если это допустимый хеш.

JSON.parse(article.reload.data,:symbolize_names => true)

Этот метод рекурсивно символизирует все ключи.Это не сохранит никакого смешивания символа и строки.

Но в вашем случае, если вы пропустили типы данных, вам также необходимо проверить, является ли элемент массива хэшем или строкой.Вы можете попробовать это, используя Kernel#eval:

def valid_hash?(string)
  eval(string).is_a?(Hash)
rescue SyntaxError
  false
end

Подробнее о eval методе здесь

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