使用postgis数据使用find_by_sql进行ActiveRecord查询

时间:2019-04-11 16:43:19

标签: ruby-on-rails postgis

到目前为止,我只能够运行涉及两个表的所有记录的find_by_sql查询来查找相交。

Regionpolygon.where('nation_id = ?', 74).find_by_sql "SELECT regionpolygons.id, area_name, destinations.id 
  FROM regionpolygons, destinations 
  WHERE ST_Intersects(regionpolygons.polygon_area, destinations.latlon)"

需要实现的两个目标是:

  • 具有较小的子集,可从该子集查询regionpolygons @rps = Regionpolygon.where('nation_id = ?',74).all。这似乎很有效。
  • 从目标表@dests = Destination.all @dests.each do |dest| [...]提供一个点,以便迭代可以更新记录属性 实例变量添加到这种类型的查询中后似乎无法很好地消化

该查询该如何制定?

1 个答案:

答案 0 :(得分:1)

您的问题尚不清楚,但是您只是在寻找一种可管理的编程方式来生成该查询,然后可以使用arel进行此搜索,如下所示

rp_table = Regionpolygon.arel_table
destination_table = Destination.arel_table

query = rp_table.project(rp_table[:id], 
           rp_table[:area_name], 
           destination_table[:id].as('destination_id')
   ).join(destination_table).on(
       Arel::Nodes::NamedFunction.new('ST_Intersects', 
         [rp_table[:polygon_area], destination_table[:latlon]]
       )
   ).where(rp_table[:nation_id].eq(74))

这将产生以下SQL

SELECT 
    [regionpolygons].[id], 
    [regionpolygons].[area_name], 
    [destinations].[id] AS destination_id 
FROM 
    [regionpolygons] 
    INNER JOIN [destinations] ON 
        ST_Intersects([regionpolygons].[polygon_area], [destinations].[latlon])     
WHERE 
    [regionpolygons].[nation_id] = 74

您可以通过直接调用queryto_sql转换为SQL。因此:

ActiveRecord::Base.connection.exec_query(query.to_sql).to_hash

将执行上面找到的行中返回的Array,其中将行转换为哈希。该哈希看起来像:

 {"id" => 1, "area_name" => "area_name", "destination_id" => 1}