【问题标题】:How can I filter ActiveAdmin index listings by a join table?如何通过连接表过滤 ActiveAdmin 索引列表?
【发布时间】:2014-01-09 19:37:31
【问题描述】:

假设我有一个表posts,另一个表reviews 有一个post_id 和一个rating(整数)。

如何向app/admin/post.rb 添加过滤器以返回具有特定总分的帖子? (例如 SUM(reviews.rating) GROUP BY (posts.id))。我希望过滤器与其他过滤器一起显示在索引的右侧,理想情况下用作范围输入。

明确地说,当我说“过滤器”时,我的意思是 ActiveAdmin filter 方法,它将过滤器添加到索引页面的右侧边栏。

我在 Post 中创建了一个范围,它返回带有分数的帖子,但我无法找到在 ActiveAdmin 过滤器中使用它的方法。

注意:我重写了我的示例,因为我原来的示例没有捕捉到问题的复杂性。

【问题讨论】:

  • 我很困惑;您想将这些查询作为过滤器、范围还是两者兼而有之?
  • 最终目标是能够过滤来自帖子索引页面的计算值。我编写了一个范围,因为我想确保查询是正确的,并且我认为这将是一种将其添加到 ActiveAdmin 的灵活且简单的方法。然而,到目前为止,我还没有找到一种方法来做到这一点。

标签: ruby-on-rails ruby activeadmin ransack


【解决方案1】:

我还没有为这个问题想出合适的解决方案,但我找到了解决方法。

我可以根据查询参数更改 scoped_collection,并在我想使用它时简单地传递参数。例如,如果我有一个 with_rating(x) 范围,它返回分数至少为 x 的帖子,我可以这样写:

controller do
  def scoped_collection
    if params[:with_rating]
      super.with_rating(params[:with_rating])
    else
      super
    end
  end
end

然后我可以转到/admin/posts?with_rating=100 并返回评分至少为 100 的帖子。

感谢@seanlinsley 让我了解我在此解决方案中使用的scoped_collection 方法。

【讨论】:

    【解决方案2】:

    提高性能是common to override scoped_collection to join associated records

    ActiveAdmin.register Post do
      controller do
        def scoped_collection
          super.includes :author, :publisher
        end
      end
    end
    

    由于现在整个集合都包含作者和出版商,因此您可以拥有一个查询这些内容的范围:

    scope :random_house do |scope|
      scope.where publishers: {name: 'Random House'}
    end
    

    【讨论】:

    • 这看起来确实很有用,但我仍然不知道如何使用该范围添加过滤器。我希望像filter scope: :random_house, as: :checkbox 这样的东西。
    • 虽然在我的情况下它更棘手,因为我的值是计算出来的,所以我需要 Ransack 生成HAVING SUM(reviews.rating) > 100 或类似的东西(而不是使用 WHERE)。这就是为什么我希望使用我已经编写的范围,而不是必须弄清楚如何让 Ransack 生成复杂的 SQL。
    • filter scope: :random_house, as: :checkbox 最好写成一个选择框,以便从不同的发布者中进行选择。例如:filter :publisher_name, as: :select, collection: ->{Publisher.uniq.pluck :name}
    • 同意 - 对于你的例子,这很好。但我希望它在作用域上工作的原因是可以查询 SQL 聚合函数。
    【解决方案3】:

    使用计数器缓存列存储 cmets 计数

    http://railscasts.com/episodes/23-counter-cache-column

    然后,每次对该帖子创建评论时,该列都会更新。这也有助于提高搜索性能。

    【讨论】:

    • 谢谢。这种情况实际上比我给出的例子更复杂,所以计数器缓存不起作用。我试图保持简单,但显然我的例子太简单了:) 我已经更新了我的问题来解释这一点。你知道直接查询连接模型/范围的方法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 2017-11-24
    • 1970-01-01
    • 2022-11-11
    • 2015-11-02
    • 2012-08-04
    • 2013-09-19
    相关资源
    最近更新 更多