当模型具有RGeo属性时Address
有一个典型的模式:
t.st_point :coordinates, geographic: true, srid: 4326
通常它被包装在RGeo::Geographic::SphericalPointImpl
类中
Realty.last.address.coordinates
#<RGeo::Geographic::SphericalPointImpl:0x2b1a364b429c "POINT (106.5 10.5)">
但在某些情况下,它被完全不合适的笛卡尔包装器包裹RGeo::Cartesian::PointImpl
Realty.joins(:address).select('realties.id, addresses.coordinates::geometry').first.coordinates
#<RGeo::Cartesian::PointImpl:0x2b1a364a691c "POINT (106.0 10.0)">
我正在使用最新的'activerecord-postgis-adapter 3.1.4'
rails 4.2.4
也许有人知道如何解决这个问题,即coordinates
总是返回RGeo::Geographic::SphericalPointImpl
实例?
当您选择带有 addresses.coordinates::geometry
的列时,您将强制 Postgres 返回几何类型的列。当你执行Realty.last.address.coordinates
时,你会返回一个不同的SQL类型(一个点(。
我会从您的 SQL 查询中删除::geometry
。
来自 https://github.com/rgeo/rgeo-activerecord#spatial-factories-for-columns 的文档:
activerecord-postgis-adapter
使用 SpatialFactoryStore
类作为查找类型的注册表将 SQL 类型转换为 ruby 类型。
在SpatialFactoryStore
单一实例类中注册空间工厂。ActiveRecord 模型中的每个空间类型都将使用该SpatialFactoryStore
检索与其类型属性匹配的工厂。例如,您可以为点类型、与特定 SRID 匹配的类型、具有 Z 坐标或属性的任意组合设置不同的空间工厂。
此处列出了注册空间类型时支持的键及其默认值和其他允许的值:
geo_type: "geometry", # point, polygon, line_string, geometry_collection,
# multi_line_string, multi_point, multi_polygon
has_m: false, # true
has_z: false, # true
sql_type: "geometry", # geography
srid: 0, # (any valid SRID)
默认工厂RGeo::Geographic.spherical_factory
地理类型,RGeo::Cartesian.preferred_factory
几何类型。
下面是一个设置示例:
RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
# By default, use the GEOS implementation for spatial columns.
config.default = RGeo::Geos.factory_generator
# But use a geographic implementation for point columns.
config.register(RGeo::Geographic.spherical_factory(srid: 4326), geo_type: "point")
end