Запрос ActiveRecord с find_by_sql для данных postgis

#ruby-on-rails #postgis

#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 похоже, работает..
  • предоставление единой точки из таблицы destinations @dests = Destination.all @dests.each do |dest| [...] , чтобы итерация могла позволить обновлять атрибуты записи переменные экземпляра, похоже, не очень хорошо усваиваются при добавлении к этому типу запроса

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

Ответ №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
  

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

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

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

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

Комментарии:

1. поскольку целью является перебор коллекции, я изменил предложение where на ).where(rp_table[:nation].eq(74).and(destination_table[:id].eq(4079))) . Очень четкий и, следовательно, полезный ответ; Я полностью пропустил AREL, но удивляюсь, почему find_by_sql был таким «нераскрытым» …