【问题标题】:Rails - get polymorphic children from collection as ActiveRecord::RelationRails - 从集合中获取多态子项作为 ActiveRecord::Relation
【发布时间】:2018-05-02 01:34:48
【问题描述】:

我需要从父级获取所有子级作为 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 之类的东西,但它们不是用于检索对象,而是用于检索列数据。我可以尝试像这样搜索每个孩子类型的 ID

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)

但它不能扩展,因为我需要为我想从搜索结果中获取的每个对象都这样做。

任何帮助将不胜感激。

编辑 这是一些演示该问题的基本伪代码: 类配置文件 :searchable 结束

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 来进一步过滤它们?

【问题讨论】:

    标签: ruby-on-rails activerecord children polymorphic-associations pg-search


    【解决方案1】:

    我不熟悉这个库。但是,查看您的代码,我猜想任何尝试使用 CollectionProxy 并在其上映射一些函数都会触发评估 CollectionProxy 并返回一个数组。

    快速浏览了库 GitHub 文档,也许这样的东西可能有用:

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

    【讨论】:

    • 感谢您的回答。这是一个可行的选择,与我给出的最后一个示例非常相似。我想将某些函数映射到集合将返回一个数组是有道理的。可悲的是,对于我的情况,通过按类型拆分结果并执行Post.where(pg_search_document: post_docs),我失去了太多优势,它不会扩展,我失去了排名等顺序。有没有办法直接从查询中获取这个集合?
    • 这些对象(帖子、个人资料等)是否共享一些不只是 PgSearch::Document 类的一部分的通用接口?我想看看你打算如何使用这种关系;也许你可以给我们几行伪代码来告诉我们你想用这个 ActiveRecord::Relation 做什么?
    • 我也很难看到你想要实现的目标取决于是一个关系,而不是一个数组,但PgSearch.multisearch('query').includes(:searchable)没有回答
    • 我基本上希望能够从查询中动态过滤结果。在这种特定情况下,我想使用与limit(x).offset(y) 相同的paginate(page: params[:page]) 对结果进行分页。我一直在阅读,这个问题并不是 pg_search 特有的,而是一般的多态关联。我将尝试添加一些演示此问题的基本代码。
    • @AlejandroAristizábal 当然,但是如果您要获取一页数据并显示它,您会向用户显示哪些字段?个人资料和帖子是否有一些共同的数据(排名?)?此数据是配置文件(例如)还是 pg_doc 的一部分?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    相关资源
    最近更新 更多