0

DB の「病気」テーブルを検索する単純な検索フォーム (「単純なフォーム」スクリーンキャストによる) を実装しました。ここで、同じ検索ボックスで「病気」テーブルと「症状」テーブルの両方を検索する必要があります。

私のコードは現在次のようになっています。

メインページ\index.html.erb:

<b>Illnesses</b>
    <%= form_tag illnesses_path, :method => 'get' do %>
      <p>
        <%= text_field_tag :search, params[:search] %><br/>
        <%= submit_tag "Illnesses", :name => nil %><br/>
      </p>

病気_コントローラー.rb:

class IllnessesController < ApplicationController
    def index
    @illnesses = Illness.search(params[:search])

    respond_to do |format|
        format.html # index.html.erb
        format.json { render json: @illnesses }
    end
    ...
end

病気.rb:

class Illness < ActiveRecord::Base
    ...

    def self.search(search)
    if search
        find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
    else
        find(:all)
    end
 end

この拡張機能の実装方法を教えてください。私は(明らかに)初心者で、「form_tag」アクションがどうあるべきか、どこに実装する必要があるのか​​ 、どのクラスが拡張検索を実装する必要があるのか​​ よくわかりません...

ありがとう、リー

4

1 に答える 1

1

うーん、病気クラスに似た症状クラスがあると仮定して簡単に始めるには(ところで、検索機能をモジュールにリファクタリングしてから、このモジュールを両方のクラスに含めると最もきれいになります)、次のことができます:

class IllnessesController < ApplicationController
  def index
    @results = Illness.search(params[:search]) + Symptom.search(params[:search])
    ...
  end
end

しかし、コントローラーの名前をリファクタリングしたいと思うかもしれません。これはもはや Illness 固有のものではないからです。また、ここでは 1 つではなく 2 つの検索クエリを使用しているため、最適ではありませんが、2 種類のモデルに対して純粋な SQL クエリを同時に送信する手間が省けます。

モジュールは大丈夫です。モジュールに慣れていない場合、モジュールは少し奇妙に思えるかもしれませんが、クラス間で共有して物事を DRY に保つことができるコードにすぎません。モジュールからコードを取得し、それをクラスのコンテキストで評価する (インタープリター言語のおかげで) モジュールを含めると、モジュール コードがクラス自体にハード コードされている場合と同じ結果になると想像できます。したがって、モジュールは次のようになります。

module Search
  def self.search(token)
    find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
  end
end

そして、find メソッド (ActiveRecord API) を実装しているクラスであれば、このモジュールを喜んでインクルードして、次のような検索機能を楽しむことができます。

require 'path/to/search'

class Foo < ActiveRecord::Base
  include Search
end

それでおしまい。検索コードを微調整する必要がある場合は、1 か所で変更すると、すべてのインクルーダーに反映されます。次のように使用されることもあるモジュール内にモジュールを作成することもできます。

require 'active_support/concern'

module Search
  extend ActiveSupport::Concern

  included do
    #Stuff that gets done when the module is included (new validations, callbacks etc.)
  end

  module ClassMethods
    #Here you define stuff without the self. prefix
  end

  module InstanceMethods
    #Instance methods here
  end
end

しかし、その一部は ActiveSupport::Concern で定義されている慣例であるため、すべてが純粋な ruby​​ で機能するとは限りません。これらのことを試してみることをお勧めします。それらは Ruby を本当に楽しくします。ああ、extend は include と非常によく似ていますが、私が理解しているように、クラス レベルで評価するようなものです。したがって、私に従えば、インクルード モジュールのすべてのインスタンス メソッドがインクルード モジュールのクラス メソッドになります。楽しむ!

于 2012-06-03T16:28:57.420 に答える