我需要在Ruby的SQL SELECT子句中执行PostGIS函数st_intersection
。目前,我将其作为原始SQL查询:
sql_query = "SELECT id, ST_ASEWKT(ST_INTERSECTION(geometry, ?)) FROM trips WHERE status='active';"
intersections = Trip.execute_sql(sql_query, self[:geometry].to_s)
这种方式的缺点是我以文本形式接收结果,并且需要从字符串中解析出对象。使用ActiveRecord接口进行查询会更好。但是,我找不到在ActiveRecord中运行PostGIS功能(例如st_intersection
)的任何解决方案。
activerecord-postgis-adapter的早期版本README显示了一个使用宝石squeel
的好例子:
my_polygon = get_my_polygon # Obtain the polygon as an RGeo geometry
MySpatialTable.where{st_intersects(lonlat, my_polygon)}.first
由于这不再是当前自述文件的一部分,我想知道是否建议不要这样做,或者是否有更好的选择。
答案 0 :(得分:2)
这里要解决两个问题。
第一个是在.select
子句中使用SQL函数。通常,这很容易-您只需使用AS
为结果命名。这是来自ActiveRecord Rails Guide的示例:
Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)")
生成的Order对象将具有ordered_date
和total_price
属性。
这给我们带来了第二个问题,那就是Rails没有给我们提供一种简单的方法来参数化select
(即使用?
占位符),因此(据我所知)告诉),您需要自己使用sanitize_sql_array
:
sql_for_select_intersection = sanitize_sql_array([
"ST_ASEWKT(ST_INTERSECTION(geometry, ?)) AS intersection",
geometry,
])
这将返回经过清理的SQL片段,例如ST_ASEWKT(ST_INTERSECTION(geometry, '...'))
,您可以使用该片段在select
中指定字段:
Trip.where(status: "active").select(:id, sql_for_select_intersection))
结果查询将返回具有id
和intersection
属性的Trip对象。