在Kaminari中对多个模型进行分页

22

我正在创建一个搜索页面,可以在应用程序内对用户、帖子和评论进行全局搜索。目前我有:

# POST /search
def index
  query = params[:query]
  @users = User.search(query).page(params[:page])
  @posts = Post.search(query).page(params[:page])
  @comments = Comment.search(query).page(params[:page])

  respond_to do |format|
    format.html
  end
end

然而,我真的想得到一个所有结果都混合在一起再分页的东西。有哪些策略可以做到这样的分页搜索呢?谢谢!

3个回答

52

自从这个提交:https://github.com/amatsuda/kaminari/commit/f9f529fb68ab89feea38773a4c625c1b14859128

你可以做以下事情:

在你的视图中,你可以这样做:

<%= paginate @users, :remote => true, :param_name => "user_page" %>
<%= paginate @posts, :remote => true, :param_name => "post_page" %>
<%= paginate @comments, :remote => true, :param_name => "comment_#{some_post_id}_page" %>

然后在您的控制器中,您可以这样引用它们:

@users = User.search(query).page(params[:user_page])
@posts = Post.search(query).page(params[:post_page])
@comments = Comment.search(query).page(params[:comment_page])

在您的视图的 js.erb 文件中,您可能会有以下内容:

$('#posts').html('<%= escape_javascript render(@posts) %>');
$('.table-pager').html('<%= escape_javascript(paginate(@posts, :remote => true).to_s) %>');

1
Michael,感谢您提供非常好、清晰和简明的答案。如果您能够扩展您的答案并提供必要的JavaScript来处理这种情况,那将非常有帮助。我是一个JavaScript新手,正在努力尝试让Kaminari作者的JavaScript示例在多个模型中工作。 - Don Leatham
这里有很棒的信息!帮助我解决了我遇到的问题。 - matthewvb
2
@Don,如果您想要一个快速简单的解决方案而不需要使用JavaScript,请删除“:remote => true”。 - Eduardo
@Michael K Madison,有什么线索吗?我也在 JavaScript 部分挣扎。 - Petros Kyriakou
@PetrosKyriakou 希望我的额外编辑可以更好地说明问题。 - Michael K Madison

1
在考虑解决方案之前,您需要首先明确定义最终结果应该是什么。如果您想在结果页面上显示每种记录的几个,则可以修改您发布的方法并使用以下方法组合三个分页结果:
@results = @users + @posts + @comments
@results.sort! { |a, b| a.score(query) > b.score(query) }

每个对象都需要有一个实例方法“score”,以便根据查询优先级进行排序。此外,您需要修改视图以正确呈现每个项目,并确保在具有最多页面的模型上调用分页。
或者,更强大的方法是添加全文搜索服务(例如Index TankWeb SolrThinking Sphinx)。这些技术的热门程度变化很快,因此请进行一些研究,找到适合您需求的服务。示例语法如下:
User.multi_solr_search query, models: [Post, Comment]

-1
你可以将查询结果和页面结合起来运行。
users = User.search(query)
posts = Post.search(query)
comments = Comment.search(query)
@results = users + posts + comments
@results.page(params[:page])

5
kaminaripaginate 这样的宝石的好处之一是它们使用 SQL 的 limitoffset 子句。如果您以这种方式解决问题,就会失去这个好处! - Kevin Sylvestre
啊,糟糕。我的错,我本来想建议使用全文搜索,因为使用AR进行搜索感觉像是一个丑陋的hack。 - Devin M
@KevinSylvestre,你找到了一个好的解决方法吗?除了将所有这些模型保存在单个表中,还有其他简便的方法吗?很高兴在这里见到你! - elsurudo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接