2012-06-03 165 views
0

我已经实现了一个简单的搜索表单(根据“简单表单”屏幕截图),用于搜索我的数据库中的“疾病”表。 现在我想要相同的搜索框来搜索“疾病”表和“症状”表。ruby​​ on rails实现搜索多个关系的搜索表单

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

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 

可以y ou请指导我如何实现这个扩展? 我是一个初学者(显然),我真的不知道应该是什么“的form_tag”的行动,我应该在哪里实现它和类实现扩展搜索...

感谢, 李

+0

你在使用Rails 2.x或3.x吗?看起来像2.x,但如果你是新手,那么你会希望从3.x开始 –

+0

其实我使用rails 3.2.3 ..我使用旧的语法吗? – user429400

+0

是的,'find(:all)'是旧的。你想'where'语法。 –

回答

1

嗯,为了简单起见,假设你有一个类似于疾病类的症状类(如果你将搜索功能重构为一个模块,然后将这个模块包含在这两个类中,它将是最干净的),那么你可以做:

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 ::关注所以不是一切都将在纯Ruby或许工作约定。我鼓励你试验这些东西,它们让红宝石变得真正有趣。哦,扩展非常像包含,只是,据我了解,它是在课堂上评估的。因此,如果您关注我,包含模块的所有实例方法都将成为包装器模块的类方法。玩的开心!

+0

谢谢。如果我想要为您提供的干净解决方案,我的搜索模块应该如何?你在两个课程中包含什么意思? (我只是在寻找高层次的解释,这种语言与我所熟悉的任何东西都是如此不同......) – user429400

+0

给我一段时间。我将编辑我的文章,以便您可以在所有降价的地方看到它;-) – Renra