Tenho uma aplicação Rails usando Postgres como banco de dados.
O Postrgres não aceita strings contendo bytes nulos (exemplo: "a \u0000 b"
). Tentar salvar esses dados leva ao seguinte erro:
ActiveRecord::StatementInvalid
PG::UntranslatableCharacter: ERROR: unsupported Unicode escape sequence
Gostaria de configurar uma regra que funcionasse para todos os meus modelos ActiveRecord, garantindo que cada atributo de string removesse bytes nulos dele antes de salvar. Estou pensando em algo que poderia ter um efeito semelhante ao exemplo abaixo:
class MyModel < ApplicationRecord
before_save :remove_null_bytes
private
def remove_null_bytes
my_field.delete!("\u0000")
end
end
Mas aplicado a cada atributo de string de cada modelo sem ser forçado a defini-lo repetidamente.
O motivo pelo qual quero que isso seja limitado aos atributos de string do Active Record é que o aplicativo também manipula uploads binários e webhooks de e-mail. Eles podem conter bytes nulos legítimos, e não quero que sejam afetados pela nova regra.
Quando você quiser normalizar todos os atributos do tipo string em todos os modelos, eu adicionaria isto a
ApplicationRecord
:Observe que isso
normalizes
foi introduzido no Ruby on Rails 7.1 e não está disponível em versões mais antigas.Estou pensando em definir algo assim em
ApplicationRecord
:Não tenho certeza se estou feliz com a metaprogramação e a falta de legibilidade dessa abordagem.
Substitua write_attribute em ApplicationRecord para garantir que todos os atributos de string sejam higienizados quando atribuídos:
não há necessidade de adicionar o método before_save