Я пытаюсь преобразовать «сырой» запрос PostGIS SQL в запрос Rails ActiveRecord. Моя цель состоит в том, чтобы преобразовать два последовательных запроса ActiveRecord (каждый из которых принимает ~ 1 мс) в один запрос ActiveRecord (~ 1 мс). Используя SQL ниже с ActiveRecord::Base.connection.execute
, я смог проверить сокращение времени.ActiveRecord Subquery Inner Join
Таким образом, мой прямой запрос - помочь мне преобразовать этот запрос в запрос ActiveRecord (и лучший способ его выполнения).
SELECT COUNT(*)
FROM "users"
INNER JOIN (
SELECT "centroid"
FROM "zip_caches"
WHERE "zip_caches"."postalcode" = '<postalcode>'
) AS "sub" ON ST_Intersects("users"."vendor_coverage", "sub"."centroid")
WHERE "users"."active" = 1;
ПРИМЕЧАНИЕ, что значение <postalcode>
является единственными переменными данными в этом запросе. Очевидно, что здесь есть две модели: User
и ZipCache
. User
не имеет прямого отношения к ZipCache
.
Текущий двухступенчатый запрос ActiveRecord выглядит следующим образом.
zip = ZipCache.select(:centroid).where(postalcode: '<postalcode>').limit(1).first
User.where{st_intersects(vendor_coverage, zip.centroid)}.count
Одним из наиболее важных советов, которые я узнал, является то, что, хотя приятно, что вы можете использовать методы в Ruby, если вы цепляетесь в свой код, это означает, что вы не следуете [Law Of Demeter] (http: /en.wikipedia.org/wiki/Law_of_Demeter). Не начинайте, глядя на ваш SQL-запрос, вы должны смотреть на свой ZipCache.select.where.limit.first и видеть, как вы можете уменьшить количество методов, перемещая логику вниз. Немного странно, что вы приближаетесь к запросу, начинающемуся с ZipCache, а не к модели User ... Я что-то упустил? – christoshrousis
Я бы предположил, что часть, которую вы «пропустили», состоит в том, что требуется цепочки ActiveRecord. Я смею писать запрос ActiveRecord, который выбирает и заполняет только одну модель и только одно свойство и говорит мне, как это сделать без цепочки методов. Что-то говорит мне, что вы педантичны в LoD. Это было сказано много раз, но повторяется [Закон Деметры не является упражнением для подсчета точек] (http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx/). – Ryan