#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 был таким «нераскрытым» …