Это действительно просто классический c пример стрельбы в ноги с плохим моделированием базы данных.
Postgres массивы - хороший инструмент для действительно специализированных задач, где у вас есть массив простых скалярных значения, такие как целые числа или строки. Они не очень хорошая идея, если вы хотите хранить хэши. Если вы поместите Ruby га sh внутрь столбца массива, вы получите незапрашиваемый беспорядок.
Тип JSON / JSONB может хранить более сложные структуры, такие как массив объектов, и является допустимым выбором. если данные не поддаются какой-либо попытке подтвердить схему. В то время как вы можете запрашивать массив объектов с помощью оператора include:
SELECT *
FROM "drinkers"
WHERE habits @> '[{"year": 2020}]'
Вы действительно не оказываете здесь никакой пользы, если данные структурированы. Как только вы увеличите сложность, запросы будут отвратительными, и у вас не будет никаких индексов, которые бы ускоряли их.
Вместо этого вы просто хотите столкнуться с фактами, что реляционные базы данных являются табличными и способ моделировать данные в реляционной базе данных - это, как вы уже догадались, таблицы.
class Drinker < ApplicationRecord
has_many :habits
end
class Habit < ApplicationRecord
belongs_to :drinker
end
Drinker.joins(:habits)
.where(habits: { year: 2020 })
TLDR; массив, JSON / JSONB и hstore являются достойными инструментами для действительно специализированных работ. Но никогда не должен быть вашим первым выбором для чего-либо.