Запрос ActiveRecord с find_by_sql для данных postgis - PullRequest
0 голосов
/ 11 апреля 2019

На сегодняшний день мне удалось только выполнить запрос 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)"

Две цели, которые должны быть достигнуты:

  • с меньшим подмножеством, из которого можно запросить регион-полигоны @rps = Regionpolygon.where('nation_id = ?',74).all Кажется, это работает ..
  • предоставление одной точки из таблицы адресатов @dests = Destination.all @dests.each do |dest| [...], чтобы итерация могла обновлять атрибуты записи переменные экземпляра, по-видимому, не очень хорошо усваиваются при добавлении в запрос этого типа

Как можно сформулировать этот запрос?

1 Ответ

1 голос
/ 11 апреля 2019

Ваш вопрос немного неясен, но если вы просто ищете управляемый и программный способ генерации этого запроса, вы можете выполнить этот поиск с помощью 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

Вы можете преобразовать query в SQL, буквально вызвав to_sql.Итак:

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

Вернет Array найденных строк, выполняя вышеуказанное, где строки конвертируются в хэши.Этот хеш будет выглядеть так:

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