Я хочу хранить массив объектов в столбце JSONB в PostgreSQL. Я использую Rails 5.2. Я использую пользовательский сериализатор, который гарантирует, что значение, присвоенное полю JSONB, является массивом, а не хешем. И я получаю сообщение об ошибке при назначении что-то вроде [{a: 1}]
для поля. Вот код:
модель
class Printing
serialize :card_faces, CardFacesSerializer
end
сериализатору
class CardFacesSerializer
include JSONBArraySerializer
def allowed_attributes
%i[name image]
end
end
концерн сериализатора :
module JSONBArraySerializer
extend ActiveSupport::Concern
def initialize(data)
return [] if data.blank?
if data.is_a?(String)
json = Oj.load(data, symbol_keys: true)
end
raise ArgumentError, "#{json} must be [{},{}], not {}" if json.is_a?(Hash)
# Will only set the properties that are allowed
json.map do |hash|
hash.slice(self.allowed_attributes)
end
end
class_methods do
def load(json)
return [] if json.blank?
self.new(json)
end
def dump(obj)
# Make sure the type is right.
if obj.is_a?(self)
obj.to_json
else
raise StandardError, "Expected #{self}, got #{obj.class}"
end
end
end
end
При оценке:
pr = Printing.first
pr.card_faces = [{hay: 12}]
pr.save!
Я получаю ошибку:
StandardError: Ожидается CardFacesSerializer, получен массив
Не думаю, что мне понятно, как работает dump / load. Почему dump
вызывается во время сохранения? Как я могу исправить мой код для правильной работы?
UPDATE
Мне удалось заставить его работать с этим кодом концерна сериализатора:
module JSONBArraySerializer
extend ActiveSupport::Concern
class_methods do
def load(data)
return [] if data.blank?
if data.is_a?(String)
json = Oj.load(data, symbol_keys: true)
end
raise ArgumentError, "#{json} must be [{},{}], not {}" if json.is_a?(Hash)
# Will only set the properties that are allowed
json.map do |hash|
hash.slice(*allowed_attributes)
end
end
def dump(obj)
# Make sure the type is right.
if obj.is_a?(Array)
obj.to_json
else
raise ArgumentError, "Expected Array, got #{obj.class}"
end
end
end
end