标头部分中的 ransack 搜索表单:未向 search_form_for 提供 Ransack::Search 对象

Posted

技术标签:

【中文标题】标头部分中的 ransack 搜索表单:未向 search_form_for 提供 Ransack::Search 对象【英文标题】:ransack search form in header partial: No Ransack::Search object was provided to search_form_for 【发布时间】:2012-05-18 09:51:01 【问题描述】:

首先,我是 RoR 的新手,所以答案可能很明显,在这种情况下,我深表歉意。我环顾四周,没有发现任何有用的东西。

我正在尝试在我的应用程序的每个网页的标题处设置一个搜索表单,该表单将搜索我所有“存储桶”的名称。以下是相关代码:

在 app/views/layouts/_header.html.erb 中(在导航栏中):

<% search_form_for @q do |f| %>
  <%= f.label :name_cont %>
  <%= f.text_field :name_cont %>
  <%= f.submit %>
<% end %>

在 app/controllers/buckets_controller.rb 中:

def index
  unless params[:q].blank?
    @q = Bucket.search(params[:q])
    @buckets = @q.result.paginate(:page => params[:page])
  else
    @buckets = Bucket.find(:all, :limit => 5).paginate(:page => params[:page])
  end
end

我知道最后一部分不是那么好:我想要做的是,如果我只是访问存储桶索引页面(而不是通过搜索),我会显示 5 个最近创建的存储桶。当我在标题表单中搜索某些内容时,我会访问索引页面,但只显示命中搜索的存储桶。 (将搜索页面与我的索引页面分开是否有更好的处理方法?)

我发现 this issue 几乎相同,但我仍然不知道如何处理 @q 如果每个页面上都有表单——当然我不必更改每个控制器的每一个动作?

对不起,我的笨拙是因为你的任何挫折!

【问题讨论】:

我浏览了推荐的记录,但没有运气。可以分享一下你的答案吗 @Vezu 查看新答案。 【参考方案1】:

正如其他人所说,您需要利用 ApplicationController 的 before_filter。虽然 ernie 本人似乎并不推荐这样做,但实现起来很简单。

首先,使用高级 Ransack 选项设置搜索路径

#config/routes.rb
  resources :buckets do
    collection do
      match 'search' => 'buckets#search', via: [:get, :post], as: :search
    end
  end

其次,更新您的 BucketsController 以包含以下自定义操作:

#controllers/buckets_controller.rb
  def search
    index
    render :index
  end

还没有什么不寻常的。如果您当前尝试搜索,您将从原始问题中得到错误。您对变量 q 的定义已正确实现,但您必须将其移至 ApplicationController,如下所示:

#controllers/application_controller.rb
before_filter :set_global_search_variable

  def set_global_search_variable
    @q = Bucket.search(params[:q])
  end

最后,更新您的搜索表单以传递正确的搜索选项

#layouts/_header.html.erb

    <% search_form_for @q, url: search_buckets_path, html:  method: :post   do |f| %>
      <%= f.label :name_cont %>
      <%= f.text_field :name_cont %>
      <%= f.submit %>
    <% end %>

【讨论】:

有效。这样,搜索 url 就变成了my-rails-app.com/buckets/search【参考方案2】:

不,您不需要编辑所有控制器。

您可以使用 ApplicationController 来满足所有“常见”控制器的需求。阅读指南 http://guides.rubyonrails.org/action_controller_overview.html 和 API 文档 http://api.rubyonrails.org/classes/ActionController/Base.html

这里的关键是,当您生成新的 rails 应用程序时,您会注意到它创建了文件 .../app/controllers/action_controller.rb 并且该类派生自 ActionController::Base。然后,如果您再次使用 rails 生成器为您的应用程序创建控制器,您会注意到您的新控制器类派生自 ApplicationController(而不是 ::Base)。这意味着 application_controller.rb 是您的应用程序的父控制器类。这意味着其中的所有内容都可供您的所有应用程序控制器使用。这很容易被滥用,所以要明智。

【讨论】:

【参考方案3】:

看起来这是不可能的。这是宝石作者 Ernie 的评论。

您必须在 before_filter 或 (ick) 在视图部分本身。如果您要放置搜索字段 网站的每个部分,我强烈建议您考虑 搜查是否是这项工作的正确工具。你可能想要 某种倒排索引搜索设置,例如 sphinx、solr 等。

https://github.com/ernie/ransack/issues/3

【讨论】:

以上是关于标头部分中的 ransack 搜索表单:未向 search_form_for 提供 Ransack::Search 对象的主要内容,如果未能解决你的问题,请参考以下文章

Ransack 搜索表单将搜索替换为“占位符”

使用 Ransack 一次搜索多个模型

WebClient 未向 Windows Phone 中的 Web 服务发送授权标头

PHP数组未向数据库插入多行

Ransack,搜索多列,一个字段,rails 3

在 Ransack 上为 Rails 设置默认搜索参数