2014-01-09 52 views
3

比方说,我有一个表posts,另一个表reviews有一个post_idrating(整数)。如何通过连接表过滤ActiveAdmin索引列表?

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

要说清楚,当我说“过滤器”时,我的意思是ActiveAdmin filter方法,它将过滤器添加到索引页上的右侧边栏。

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

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

+0

我很困惑;你想要将这些查询作为过滤器,范围还是两者来执行? – seanlinsley

+0

最终目标是能够过滤来自帖子索引页面的计算值。我编写了一个范围,因为我想确保查询是正确的,我认为这将是一种将其添加到ActiveAdmin的灵活且简单的方法。但是,到目前为止,我还没有找到一种方法来做到这一点。 –

+0

https://github.com/activerecord-hackery/ransack/issues/70 – Fivell

回答

1

使用计数器缓存列来存储评论数

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

则列将每个注释创建于post.This时间也将增加搜索的性能有助于得到更新。

+0

谢谢。这种情况实际上比我给的例子比较复杂,所以计数器缓存将无法正常工作。我试图保持简单,但显然我做的例子太简单了:)我已经更新了我的问题来解释这一点。你知道一种直接在连接模型/范围上查询的方法吗? –

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 
+0

这当然看起来是有用的,但我仍然不知道如何使用范围,添加过滤器。 我希望得到像'filter scope :: random_house,as :: checkbox'这样的东西。 –

+0

尽管在我的情况下,它更棘手,因为我的价值是计算所以我需要Ransack来产生'HAVING SUM(reviews.rating)> 100'或类似的东西(而不是使用WHERE)。这就是为什么我希望使用我已经编写的范围,而不是必须弄清楚如何让Ransack生成复杂的SQL。 –

+0

'过滤范围:: random_house,作为::复选框'会更好地写成一个选择框以从不同的发布者中进行选择。例如:'过滤器:publisher_name,作为:: select,集合: - > {Publisher.uniq.pluck:name}' – seanlinsley

3

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

我可以根据查询参数更改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方法。