2011-06-10 5 views
19

사용자, 게시물 및 설명에 대한 응용 프로그램 검색을 수행 할 검색 페이지를 만듭니다. 내가 현재 가지고 :카미나리의 여러 모델 페이지 매기기

# 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

파트 paginate'은 절 offset'는 SQL'limit'와'사용한다는 것입니다 . 이런 식으로 문제를 풀면 그 혜택을 잃어 버리게됩니다! –

+0

아, 아 ~. AR로 검색하면 추한 해킹처럼 느껴지므로 전체 텍스트 검색을 제안하려고했습니다. –

+0

@KevinSylvestre 단 하나의 테이블에 모든 모델을 유지하는 것보다는 좋은 해결 방법을 찾았습니까? 멋진 여기를보고 있습니다! – elsurudo

44

을이 커밋 :

<%= 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" %> 

: https://github.com/amatsuda/kaminari/commit/f9f529fb68ab89feea38773a4c625c1b14859128

당신은 당신이 할 수있는보기에서 다음

을 수행 할 수 있습니다 그런 다음 컨트롤러에서 다음과 같이 참조 할 수 있습니다.

및보기의 js.erb 당신과 같이있을 수 있습니다 : kaminari`와``같은 보석의 이익의

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

Michael, 매우 훌륭하고 명확하고 간결한 대답에 감사드립니다. 이 상황을 처리하는 데 필요한 자바 스크립트로 답변을 확장 할 수 있다면 매우 도움이 될 것입니다. 나는 자바 스크립트 초보자이고 여러 모델에서 작동하도록 Kaminari 작성자의 자바 스크립트 예제를 얻으려고 힘들게 노력하고 있습니다. –

+0

여기에 훌륭한 정보가 있습니다! 제가 가지고있는 문제를 해결하는 데 도움이되었습니다. – matthewvb

+2

@Don JavaScript를 사용하지 않고 간단하게 해결하려면 ": remote => true"를 제거하십시오. – Eduardo