Rails - получить полиморфные потомки из коллекции как ActiveRecord :: Relation - PullRequest
0 голосов
/ 02 мая 2018

Мне нужно получить все дочерние элементы от родителя как ActiveRecord :: Relation. Дело в том, что эти дети хранятся в полиморфном отношении. В моем случае мне нужно разбить на страницы некоторые результаты поиска, полученные с помощью pg_search gem.

Я пробовал следующее:

results = PgSearch.multisearch('query').map(&:searchable)
# Horrible solution, N + 1 and returns an array

docs = PgSearch.multisearch('query').includes(:searchable)
results = docs.map(&:searchable)
# Still getting an array

Также рассматриваются такие вещи, как select или pluck, но они не предназначены для извлечения объектов, только данные столбца. Я мог бы попытаться найти идентификаторы для каждого типа детей, например,

Post.where(id: PgSearch.multisearch('query').where(searchable_type: "Post").select(:searchable_id)
Profile.where(id: PgSearch.multisearch('query').where(searchable_type: "Profile").select(:searchable_id)

Но это не масштабируется, поскольку мне нужно было бы делать это для каждого объекта, который я хочу получить из результата поиска.

Любая помощь будет оценена.

EDIT Вот некоторый основной псевдокод, демонстрирующий проблему: Профиль класса : для поиска конец

class Post < ApplicationRecord
  has_one :search_document, :as => :searchable
end

class Profile < ApplicationRecord
  has_one :search_document, :as => :searchable
end

class SearchDocument < ApplicationRecord
  belongs_to :searchable, plymorphic: true
end

Я хочу получить все доступные для поиска элементы как ActiveRecord :: Relation, чтобы я мог динамически фильтровать их, в данном конкретном случае, используя limit(x).offset(y)

SearchDocument.all.joins(:searchable).limit(10).offset(10)

Генерирует ошибку: невозможно быстро загрузить искомую причину полиморфного отношения

SearchDocument.all.includes(:searchable).limit(10).offset(10)

Этот загружает искомые элементы в память, но не возвращает их в запросе, вместо этого применяет фильтры к элементам SearchDocument, как и ожидалось. Это может быть временным решением, чтобы отфильтровать поисковые документы и затем получить из них искомые элементы, но столкнется с разбиением на страницы в представлениях.

Вопрос здесь такой: есть ли способ получить все доступные для поиска элементы как ActiveRecord :: Relation для дальнейшей их фильтрации?

1 Ответ

0 голосов
/ 02 мая 2018

Я незнаком с этой библиотекой. Однако, глядя на ваш код, я бы предположил, что любая попытка взять CollectionProxy и отобразить какую-то функцию поверх него вызовет оценку CollectionProxy и вернет массив.

После быстрого ознакомления с библиотекой документации GitHub, возможно, что-то вроде этого может сработать:

post_docs = PgSearch.multisearch('query').where(searchable_type: "Post")
posts = Post.where(pg_search_document: post_docs)
...