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对象。我在这里错过了什么? 或者这甚至是做这种搜索的正确方法?
感谢您的帮助提前。
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所有的控制,只需要一个外部文件(搜索模式)的摘录。在这个模型中,我可以在多个模型中搜索数据(如视频中所示),并可以根据我的需要合并搜索条件,甚至可以在其中执行一些性能恶意软件。我对结果很满意。所以感谢所有的投入。
很高兴为你效劳。 – Brian 2014-10-08 19:17:07
[这是一种方法](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
是否存在想要在数据库中存储搜索的特定原因?我了解功能,但似乎特别是对多模型搜索,这可能会变得笨拙,因为每个模型可能会有它自己的一套特点。这些搜索是否与用户或其他实体相关联?如果看起来不像创建抽象(缺少更好的单词)模型更有意义,而是通过它来运行搜索。 – engineersmnky 2014-10-06 19:25:53
@Brian 谢谢,我会在早上检查第一件事情。 --engineersmnky 你是对的,它可能会变得混乱。起初,我想存储基于用户的搜索,但在与可选的客户核对之后。你对抽象模型究竟意味着什么?时态表? – mandulis 2014-10-06 21:32:16