Postgresql сортирует хэш после его спасения
Когда я сохраняю хеш-таблицу, я хочу иметь определенный порядок (как в записи). Но Postgres сортирует это по-своему. Как мне указать сортировку для записи?
Пример:
INSERT INTO "items" ("nested_params") VALUES ($1) [["nested_params", "\"Turbo\"=>\"Some variable\",\"TV\"=>\"Some variable\",\"FM\"=>\"Some variable\"];
SELECT "items".* FROM "items" WHERE "items"."id" = $2 LIMIT 1 ["id", 5]];
Выход (рубиновый хеш):
{"FM"=>"Some variable", "TV"=>"Some variable", "Turbo"=>"Some variable"}
В записи Turbo
- 1-й ключ.
PS Я использую неанглийские ключи в хэше. Но они сортируются не по буквам в кодировке UTF-8, а случайным образом
1 ответ
Ни hstore, ни JSON изначально не упорядочены. Из прекрасного руководства hstore:
Порядок пар не имеет значения (и не может быть воспроизведен на выходе).
и из тонкой спецификации JSON:
Объект - это неупорядоченный набор пар имя / значение.
Таким образом, никому не гарантируется забота о порядке, и база данных может свободно переставлять их так, как считает нужным. То, что версия JSON поддерживает порядок, не означает, что это произойдет в следующий раз или будет после обновления, поэтому не зависит от этого неуказанного поведения.
Если вы заботитесь о порядке в вашем хэше, вам придется сделать это самостоятельно в Ruby. Простой способ сделать это - переопределить стандартный метод доступа ActiveRecord:
def nested_params
super.sort_by(&:first).to_h
end
Если ваша версия Ruby не имеет Array#to_h
тогда вы можете сказать:
def nested_params
Hash[super.sort_by(&:first)]
end
Вы можете использовать hstore
или же json
типы столбцов с этими переопределениями. Если вы хотите, чтобы сортировка не учитывала регистр, вам придется соответствующим образом настроить сортировку.