2014-10-06 2 views
3

모델을 통해 복잡한 컨트롤러에서 복잡한 검색을 구현하려고합니다. 나는 학생 모델을 가지고있다. 전체 응용 프로그램에는 모델이없는 별도의 main_controller에서 처리하는 첫 페이지가 있습니다. main_controller와 관련 인덱스 뷰는 여러 모델의 첫 페이지와 데이터를 제공합니다.레일즈 4는 별도 컨트롤러의 여러 모델을 검색합니다.

이제 여러 유형의 검색 기준으로 모델을 검색하고 싶습니다. 검색 기준은 문자열 비교, 숫자 비교 및 ​​부울입니다 (예 : 활성 인 경우 활성화 된 학생 만 표시하고 다른 모든 학생은 표시). Railscast #111은 모델 및 별도의 검색 컨트롤러를 기반으로 이러한 검색을 만드는 방법을 보여 줬습니다. 나는 그런 컨트롤러를 만들었고 정상적으로 작동합니다. 내 메인/인덱스에 관련 부분을 보여 주려고합니다. 여기에 순간에 폼/

주요 index.html.haml

- model_class = Adult 
- model_class = Pupil 
- model_class = MainSearch 

.page-header 
= render :partial => 'main_searches/form', :main_search => MainSearch.new 

그냥 전화 : 여기

는 코드입니다.

모델/main_search.rb

class MainSearch < ActiveRecord::Base 

    def pupils 
    @pupils ||= find_pupils 
    end 

    private 
    def find_pupils 
     pupils = Pupil.order(:name_sur) 
     pupils = pupils.where(id: id_search) if id_search.present? 
     pupils = pupils.where("name_first like ?", "%#{name_first}%") if name_first.present? 
     pupils = pupils.where("name_sur like ?", "%#{name_sur}%") if name_sur.present? 
     pupils = pupils.where(active: "true") if active == true #show only active or all 
     pupils 
    end 
end 

이 검색을 정의합니다.

컨트롤러 /를 railscast에 도시 된 바와 같이 main_searches_controller.rb

class MainSearchesController < ApplicationController 
    before_action :set_main_search, only: [:show, :update, :destroy] 

    def show 
    @main_search = MainSearch.find(params[:id]) 
    end 

    def new 
    @main_search = MainSearch.new 
    end 

    def create 
    @main_search = MainSearch.new(main_search_params) 

    if @main_search.save 
     redirect_to root_path, notice: 'Main search was successfully created.' 
    else 
     render action: 'new' 
    end 
    end 
end 

.

보기/main_searches/_form.html.haml 새로운 뷰를 렌더링

%h1 Advanced Search 

    = form_for :main_search, :url => main_searches_path do |f| 
    .field 
     = f.label :id_search 
     %br/ 
     = f.text_field :id_search 
    [... ommitted some fields here ...] 
    .field 
     = f.label :active 
     %br/ 
     = f.check_box :active, {}, true, false 


    .actions= f.submit "Search" 

.

보기/main_searches/_results.html.haml

%h1 Search Results 

.container-fluid 
    .row-fluid 
    .span4 

     %table.table{style: "table-layout:fixed"} 
     %thead 
      %tr 
      %th= "id" 
      %th= "name_sur" 
      %th= "name first" 
      %th= "a" 
     %div{style: "overflow-y:scroll; height: 200px"} 
     %table.table.table-striped{style: "table-layout:fixed"} 
      %tbody 
      - @main_search.pupils.each do |pupil| 
       %tr 
       %td= pupil.id 
       %td= link_to pupil.name_sur, pupil_path(pupil) 
       %td= pupil.name_first 
       %td= pupil.active 

표시 결과.

그래서 기본적으로 모든 것은 railscast에서 볼 수있는 한 모델에서 작동합니다. 내가 지금 을 필요로하는 것은 어떻게 든 사용자가 main_controller의 모든 것을 처리하게하는 것이다. 현재 캔트는 _results.html.haml 부분에 전달 된 @main_search 개체를 가져옵니다. 내가 여기서 무엇을 놓치고 있니? 또는 이와 같은 검색을 수행하는 것이 올바른 방법일까요?

미리 도움을 주셔서 감사합니다.

+0

[여기있는 접근법] (https://github.com/codeschool/FeatureFocus/blob/basecamp/app/models/search.rb) [video] (https : //www.codeschool. co.kr/screencasts/basecamp-search)를 방문하십시오. 컨트롤러에서는'@main_search = Search.for (params [: id])'와 같이 호출합니다. – Brian

+0

데이터베이스에 검색을 저장하려는 특별한 이유가 있습니까? 나는이 기능을 이해하지만 멀티 모델 검색의 경우 특히 각 모델에 특성 세트가 있기 때문에 다루기 힘들 수 있습니다. 이러한 검색은 사용자 또는 다른 엔터티와 관련이 있습니까? 그렇지 않은 경우 더 좋은 단어가없는 추상을 작성하고이를 대신 검색을 실행하는 것이 더 합리적 일 수 있습니다. – engineersmnky

+0

@Brian 감사합니다. 아침에 제일 먼저 확인해 보겠습니다. --engineersmnky 맞아요, 지저분해질 수 있습니다. 처음에는 사용자를 기준으로 검색을 저장하려고했지만 선택적인 고객과 확인한 후 추상적 모델로 정확히 무엇을 의미합니까? 임시 테이블? – mandulis

답변

2

브라이언 스 솔루션은 실제로 상당히 잘 작동합니다. 나는 관련 데이터베이스없이 별도의 모델을 생성하고 모든 검색 로직을 해당 파일에 저장합니다. 공지, 그것은 단지 클래스이며 ActiveRecord와 관련이 없습니다.

class MainSearch 

    def self.for(id_search, name_sur, name_first, active) 

     #escape for security 
     name_sur = "%#{name_sur}%" 
     name_first = "%#{name_first}%" 
     active = "%#{active}%" 

     pupils = Pupil.order(:name_sur) 
     pupils = pupils.where(id: id_search) if id_search.present? 
     pupils = pupils.where("name_first like ?", "%#{name_first}%") if name_first.present? 
     pupils = pupils.where("name_sur like ?", "%#{name_sur}%") if name_sur.present? 
     pupils = pupils.where(active: "true") if active == true #show only active or all 
    end 
end 

내 main_controller 이제이 함수를 호출하고 PARAMS 해시에서 값을 전달할 수 있습니다 :

@pupils = MainSearch.for(params[:id_search], params[:name_sur], params[:name_first], params[:active]) 

매개 변수는보기/주/_form_search.html에서 왔습니다.haml :

.search-box 
    = form_tag root_path, method: :get do 

    = label_tag :id_search 
    %br/ 
    = text_field_tag 'id_search', nil 
    %br/ 
    = label_tag :name_sur 
    %br/ 
    = text_field_tag 'name_sur', nil 
    %br/ 
    = label_tag :name_sur 
    [...] 
    = submit_tag "Submit" 

최종 단계는 결과를 보여줍니다. main_controller에서 볼 수 있듯이 @pupils 객체를 채우기 만하면 모든 뷰에서 쉽게 렌더링 할 수 있습니다. 여기

.span8 
    .row-fluid 
    %table.table{style: "table-layout:fixed"} 
     %thead 
     %tr 
      %th= "id" 
      %th= sortable "name_sur" 
      %th= "name first" 
      %th= "a" 
    %div{style: "overflow-y:scroll; height: 200px"} 
     %table.table.table-striped{style: "table-layout:fixed"} 
     %tbody 
      - @pupils.each do |pupil| 
      %tr 
       %td= pupil.id 
       %td= link_to pupil.name_sur, pupil_path(pupil) 
       %td= pupil.name_first 
       %td= pupil.active 

    = render :partial => 'form_search' 

이 설정은 main_controller의 모든 컨트롤을 유지하고 하나 개의 외부 파일 (검색 모델)가 필요 index.html.haml/주 뷰 /에서 발췌입니다. 이 모델에서는 비디오에서 볼 수있는 것처럼 여러 모델에서 데이터를 검색 할 수 있으며 검색 기준을 조합하여 제발 할 수도 있고 심지어 성능 저하를 일으킬 수도 있습니다. 결과에 상당히 만족합니다. 모든 입력에 감사드립니다.

+0

다행 이네. – Brian

관련 문제