2011-06-10 88 views
19

我正在創建一個搜索頁面,將對用戶,帖子和評論進行應用程序範圍的搜索。我目前有:分頁在Kaminari中的多個模型

# 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 

然而,我真的想得到的東西,所有的結果混合在一起然後分頁。這樣做分頁搜索的一些策略是什麼?謝謝!

回答

1

在考慮解決方案之前,您需要先確切地定義您想要的最終結果。如果你想顯示幾個每種類型的記錄結果頁面上,你可以修改你發佈的辦法和使用三者有機結合起來分頁結果:

@results = @users + @posts + @comments 
@results.sort! { |a, b| a.score(query) > b.score(query) } 

每個對象都需要有一個實例方法「分數」這將使它根據查詢優先級進行排序。此外,您需要修改視圖以處理每個項目的正確渲染,並確保在頁面最多的模型上調用分頁。

或者,更強大的方法是添加全文搜索服務(如Index Tank,Web Solr,Thinking Sphinx)。這些技術對於這些熱門技術很快就會發生變化,因此需要進行一些研究並找到適合您需求的技術。在這個例子中的語法會是這樣的:

User.multi_solr_search query, models: [Post, Comment] 
0

您可以結合來自查詢和運行頁面的結果。

users = User.search(query) 
posts = Post.search(query) 
comments = Comment.search(query) 
@results = users + posts + comments 
@results.page(params[:page]) 
+4

部分像'kaminari'和'寶石的利益paginate'是他們所使用的SQL'limit'和'offset'條款。如果你用這種方式解決問題,你會失去這種好處! – 2011-06-10 17:27:52

+0

啊,哎呀。我不好意思,我會提出全文搜索,因爲用AR搜索感覺像是一個醜陋的黑客。 – 2011-06-10 17:48:18

+0

@KevinSylvestre您是否發現了一個很好的解決方法,即將所有這些模型保存在一張表中? 看中你在這裏! – elsurudo 2014-08-26 12:52:38

44

自從這個承諾: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

邁克爾,謝謝你的非常好,清晰和簡潔的答案。如果您可以使用必要的JavaScript擴展您的答案來處理這種情況,那將會非常有幫助。我是一名JavaScript初學者,並且正在努力嘗試讓Kaminari作者的javascript示例跨多個模型工作。 – 2012-02-02 07:30:41

+0

大信息在這裏!幫助我解決了我遇到的問題。 – matthewvb 2012-09-17 14:23:38

+2

@Don提供了一個無javascript的快速簡單解決方案,只需刪除「:remote => true」即可。 – Eduardo 2014-03-02 00:00:37