there is a typical schema when Address model has an RGeo attribute:
t.st_point :coordinates, geographic: true, srid: 4326
and normally it is wrapped in the RGeo::Geographic::SphericalPointImpl class
Realty.last.address.coordinates
#<RGeo::Geographic::SphericalPointImpl:0x2b1a364b429c "POINT (106.5 10.5)">
but in some situations, it is wrapped with completely inappropriate Cartesian wrapper RGeo::Cartesian::PointImpl
Realty.joins(:address).select('realties.id, addresses.coordinates::geometry').first.coordinates
#<RGeo::Cartesian::PointImpl:0x2b1a364a691c "POINT (106.0 10.0)">
I'm using latest 'activerecord-postgis-adapter 3.1.4' with rails 4.2.4
Maybe anybody know how a way to fix this, i.e. make coordinates always return instance of RGeo::Geographic::SphericalPointImpl?
When you select the column with
addresses.coordinates::geometry, you are forcing Postgres to return a column of type geometry. When you doRealty.last.address.coordinates, you are returning a different SQL type (a point).I would remove the
::geometryfrom your SQL query.From the docs at https://github.com/rgeo/rgeo-activerecord#spatial-factories-for-columns:
activerecord-postgis-adapterconverts the SQL type to a ruby type using theSpatialFactoryStoreclass as the registry to lookup types.Register spatial factories in the
SpatialFactoryStoresingleton class. Each spatial type in your ActiveRecord models will use theSpatialFactoryStoreto retrieve a factory matching the properties of its type. For example, you can set a different spatial factory for point types, or for types matching a specific SRID, or having a Z coordinate, or any combination of attributes.The supported keys when registering a spatial type are listed here with their default values and other allowed values:
The default factories are
RGeo::Geographic.spherical_factoryfor geographic types, andRGeo::Cartesian.preferred_factoryfor geometric types.Here is an example setup: