Skip to content

Instantly share code, notes, and snippets.

@lewiseason
Last active August 5, 2020 18:28
Show Gist options
  • Save lewiseason/84cea8c4e9e182e77eda02f06a4b630e to your computer and use it in GitHub Desktop.
Save lewiseason/84cea8c4e9e182e77eda02f06a4b630e to your computer and use it in GitHub Desktop.
paper_trail & rgeo-activerecord integration
# config/initializers/paper_trail.rb
require "paper_trail_attribute_serializer_spatial_support"
PaperTrail::AttributeSerializers::AttributeSerializerFactory.include(PaperTrailAttributeSerializerSpatialSupport)
# lib/paper_trail_attribute_serializer_spatial_support.rb
module PaperTrailAttributeSerializerSpatialSupport
extend ActiveSupport::Concern
AR_SPATIAL = "ActiveRecord::Type::Spatial".freeze
included do
singleton_class.send(:alias_method, :for_original, :for)
def self.for(klass, attr)
active_record_serializer = klass.type_for_attribute(attr)
if active_record_serializer.class.name == AR_SPATIAL
SpatialSerializer.new
else
for_original(klass, attr)
end
end
end
class SpatialSerializer
def serialize(geospatial_object)
geospatial_object.to_s
end
def deserialize(string)
DEFAULT_RGEO_FACTORY.parse_wkt(string)
end
end
end

The default serializer will serialize the entire ruby object of your geospatial column. This custom serializer will serialize it to WKT (WKB isn't an option here without casting). This is much more efficient than serializing the entire ruby object, and much safer.

# config/initializers/rgeo.rb
DEFAULT_RGEO_FACTORY = RGeo::Geographic.spherical_factory(srid: 3857)
RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
config.default = DEFAULT_RGEO_FACTORY
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment