We are updating to a newer version of Rails and in previous versions saving object.to_json to a jsonb column would automatically convert it to a hash. Because of this, we expect to retrieve data from those fields as a hash.
We have no need to use the functionality of storing strings in our jsonb fields, so instead of digging through tens of thousands of lines of code to find every possible offender, I was trying to find where I could revert the behavior back to automatically saving them as hashes.
Where does it format the data it's about to save to a postgres db?
CodePudding user response:
My professional opinion would be to go through the project and fix everything, because if you try to fix the framework, any update will break and potentially undo any of the "fixes" you can try to do to make it behave like an old version of rails.
That said, if you REALLY want to dive into the nuts and bolts of rails, you can look at the following classes and override/monkeypatch them:
jsonb mappping seems to be handled by this file: https://github.com/rails/rails/blob/f95c0b7e96eb36bc3efc0c5beffbb9e84ea664e4/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID # :nodoc:
class Jsonb < Type::Json # :nodoc:
def type
:jsonb
end
end
end
end
end
end
which inherits from Type::Json
.
module ActiveRecord
module Type
class Json < ActiveModel::Type::Value
include ActiveModel::Type::Helpers::Mutable
def type
:json
end
def deserialize(value)
return value unless value.is_a?(::String)
ActiveSupport::JSON.decode(value) rescue nil
end
def serialize(value)
ActiveSupport::JSON.encode(value) unless value.nil?
end
def changed_in_place?(raw_old_value, new_value)
deserialize(raw_old_value) != new_value
end
def accessor
ActiveRecord::Store::StringKeyedHashAccessor
end
end
end
end
It seems like if you mess with the serializer and the deserializer function, you probably could achieve what you want... but again, I totally do not recommend this! You will make your codebase subject to break with any upgrade of rails. The automatic json encode and decode is probably what is messing you up.