3

別のコントローラーでモデルの複雑な検索を実装しようとしています。私は生徒のモデルを持っています。アプリ全体には、モデルを持たない別の main_controller によって処理されるフロント ページがあります。main_controller とそれに関連するインデックス ビューは、フロント ページを提供し、いくつかのモデルからデータを表示することになっています。

ここで、さまざまなタイプの検索基準をいくつか使用してモデルを検索したいと考えています。検索条件は、文字列比較、数値比較、およびブール値です (たとえば、アクティブ、true の場合はアクティブな瞳孔のみを表示、それ以外の場合はすべての瞳孔を表示)。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

現時点では、フォームへの呼び出しのみです。

models/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

これにより、検索が定義されます。

コントローラー/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 に見られるように、基本的にすべてが 1 つのモデルに対して機能します。私が今必要としているのは、ユーザーが何らかの方法で main_controller 内のすべてを処理できるようにすることです。現時点では、@main_search オブジェクトを _results.html.haml パーシャルに渡すことができません。ここで何が欠けていますか?それとも、これはそのような検索を行う正しい方法ですか?

事前にご協力いただきありがとうございます。

4

1 に答える 1

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])

パラメータは views/main/_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 オブジェクトを埋めるだけなので、どのビューでも簡単にレンダリングできます。これは、views/main/index.html.haml からの抜粋です。

.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 に保持され、1 つの外部ファイル (検索モデル) のみが必要です。このモデルでは、(ビデオで見られるように) いくつかのモデルにわたってデータを検索し、検索条件を好きなように組み合わせて、そこでいくつかのパフォーマンスの悪ふざけを行うことさえできます。私は結果に非常に満足しています。すべての入力に感謝します。

于 2014-10-07T11:28:22.123 に答える