0

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

我的代码目前如下所示:

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>

疾病控制器.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

嗯,假设你有一个类似于 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​​ 中工作。我鼓励你尝试这些东西,它们让 ruby​​ 变得真正有趣。哦,扩展很像包含,只是,据我了解,它是在类级别上评估的。因此,如果您关注我,包含模块的所有实例方法都将成为包含模块的类方法。玩得开心!

于 2012-06-03T16:28:57.420 回答