カミナリの複数のモデルをパジネートします
-
26-10-2019 - |
質問
ユーザー、投稿、コメントのアプリケーションワイド検索を行う検索ページを作成しています。私は現在持っています:
# 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つのページングされた結果を組み合わせることができます。
@results = @users + @posts + @comments
@results.sort! { |a, b| a.score(query) > b.score(query) }
各オブジェクトには、クエリの優先度に基づいてソートできるインスタンスメソッド「スコア」が必要です。また、各アイテムの正しいレンダリングを処理するためにビューを変更し、ほとんどのページでモデルでページネーションが呼び出されるようにする必要があります。
または、より堅牢な方法は、フルテキスト検索サービスを追加することです( インデックスタンク, Web solr, スフィンクスを考える)。これらの動きのためのテクノロジーはすぐに動きますので、いくつかの研究を行い、あなたのニーズに合ったものを見つけてください。これの例の例は次のようなものです。
User.multi_solr_search query, models: [Post, Comment]
他のヒント
このコミット以来: https://github.com/amatsuda/kaminari/commit/f9f529fb689feea38773a4c625c1b14859128
次のことができます
あなたの見解では、あなたはこれを行うことができます:
<%= 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) %>');
クエリと実行ページの結果を組み合わせることができます。
users = User.search(query)
posts = Post.search(query)
comments = Comment.search(query)
@results = users + posts + comments
@results.page(params[:page])