ruby on rails实现了一个搜索多个关系的搜索表单

时间:2012-06-03 16:01:51

标签: ruby-on-rails search

我已经实现了一个简单的搜索表单(根据“简单表单”截屏视频)搜索我的数据库中的“疾病”表。 现在我想要相同的搜索框来搜索“疾病”表和“症状”表。

我的代码目前看起来像这样:

main_page \ 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>

illnesses_controller.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

illness.rb:

class Illness < ActiveRecord::Base
    ...

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

您能否指导我如何实施此扩展程序? 我是一个初学者(显然),我真的不知道应该是什么“form_tag”动作,我应该在哪里实现它,哪个类应该实现扩展搜索......

谢谢, 李

1 个答案:

答案 0 :(得分:1)

嗯,只是轻易地开始假设你有一个类似于Illness类的Symptom类(顺便说一句,如果你将搜索功能重构为一个模块,然后在这两个类中包含这个模块,那将是最干净的)那么你可以做:

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

但也许您想重构控制器的名称,因为现在它不再是疾病特定的。另请注意,我们在这里使用两个搜索查询而不是一个搜索查询,因此它不是最佳的,但可以省去为两种类型的模型同时发送纯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

就是这样。现在,如果您需要调整搜索代码,可以在一个位置更改它,并将其传播到所有包含者。您还可以在模块内创建模块,有时使用这些模块:

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中起作用。我鼓励你尝试这些东西,让红宝石真正有趣。哦,扩展非常像包含,只有,据我所知,它有点评估类级别。因此,如果您关注我,所包含模块的所有实例方法都将成为包含器模块的类方法。玩得开心!