Rails 4在单独的控制器中搜索几个模型

问题描述:

我试图在单独的控制器中对模型执行复杂搜索。我有一个学生模型。整个应用程序有一个单独的main_controller处理的头版,它没有模型。 main_controller及其相关的索引视图应该提供来自多个模型的首页和显示数据。Rails 4在单独的控制器中搜索几个模型

现在我想用几种不同类型的搜索条件搜索模型。搜索标准是字符串比较,数字比较和布尔值(例如,如果为真,则只显示活动学生显示所有学生)。 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 

只需调用这里此刻的形式。

型号/ 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 

如railscast所示。

视图/ 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中所见。我现在需要的 是让用户以某种方式处理main_controller中的所有内容。此刻我不能 获得传递给_results.html.haml部分的@main_search对象。我在这里错过了什么? 或者这甚至是做这种搜索的正确方法?

感谢您的帮助提前。

+0

[这是一种方法](https://github.com/codeschool/FeatureFocus/blob/basecamp/app/models/search.rb)我在[视频](https://www.codeschool。 com/screencasts/basecamp-search)。在你的控制器中,你可以这样调用它:'@main_search = Search.for(params [:id])''。 – Brian 2014-10-06 19:04:30

+0

是否存在想要在数据库中存储搜索的特定原因?我了解功能,但似乎特别是对多模型搜索,这可能会变得笨拙,因为每个模型可能会有它自己的一套特点。这些搜索是否与用户或其他实体相关联?如果看起来不像创建抽象(缺少更好的单词)模型更有意义,而是通过它来运行搜索。 – engineersmnky 2014-10-06 19:25:53

+0

@Brian 谢谢,我会在早上检查第一件事情。 --engineersmnky 你是对的,它可能会变得混乱。起初,我想存储基于用户的搜索,但在与可选的客户核对之后。你对抽象模型究竟意味着什么?时态表? – mandulis 2014-10-06 21:32:16

Brians解决方案实际上工作得很好。我创建了一个没有相关数据库的独立模型,并将所有搜索逻辑放入该文件中。注意,它只是一个类,与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]) 

的参数来自视图/主/ _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对象,从而可以在任何视图中轻松地呈现它。下面是从视图/主/ 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所有的控制,只需要一个外部文件(搜索模式)的摘录。在这个模型中,我可以在多个模型中搜索数据(如视频中所示),并可以根据我的需要合并搜索条件,甚至可以在其中执行一些性能恶意软件。我对结果很满意。所以感谢所有的投入。

+0

很高兴为你效劳。 – Brian 2014-10-08 19:17:07