Подтвердить что ты не робот

Paginate Multiple Models в Каминари

Я создаю страницу поиска, которая будет широко использовать поиск пользователей, сообщений и комментариев. В настоящее время у меня есть:

# 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

Однако я действительно пытаюсь получить что-то, где все результаты смешиваются вместе, а затем разбиваются на страницы. Каковы некоторые из стратегий для такого поиска в разбивке по страницам? Спасибо!

4b9b3361

Ответ 1

Прежде чем задуматься о решении, вам нужно сначала определить, каким именно вы хотите получить конечный результат. Если вы хотите отобразить несколько записей каждого типа на странице результатов, вы можете изменить предложенный вами подход и объединить три разбитых на страницы результатов, используя:

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

Каждый объект должен иметь метод "score" метода экземпляра, который позволит ему сортировать на основе приоритета запроса. Кроме того, вам нужно будет изменить свое представление, чтобы обрабатывать правильную визуализацию каждого элемента и гарантировать, что разбиение на страницы вызывается на модели с наибольшим количеством страниц.

В качестве альтернативы более надежным методом было бы добавить службу полнотекстового поиска (например, Index Tank, Web Solr, Thinking Sphinx). Технология для того, что жарко для этих движется быстро, так что некоторые исследования и найти тот, который соответствует вашим потребностям. Пример синтаксиса для этого будет примерно таким:

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

Ответ 2

С момента совершения: 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) %>');

Ответ 3

Вы можете комбинировать результаты на странице запроса и запуска.

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