ransack search form in header partial: No Ransack::Search object was provided to search_form_for
Asked Answered
H

3

9

First of all, I'm new to RoR, so the answer may be obvious, in which case I apologize. I've looked around and haven't found anything that helps.

I'm trying to have a search form at the header of every web page on my app that will search through the names of all my "buckets". Here is the relevant code:

In app/views/layouts/_header.html.erb (within a nav bar):

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

In 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

I understand the last part isn't that great: what I'm trying to do is if I'm just accessing the bucket index page (not by searching), i display the 5 most recently created buckets. When I search for something in the header form, I access the index page but only show the buckets that hit the search. (would a better way to handle it to have a search page separate from my index page?)

I found this issue which is pretty much identical, but I still don't see how I handle @q if every page is going to have the form on it--surely I don't have to alter every controller's every action?

Sorry in advance for any frustration my noobishness my cause you!

Handmaid answered 9/5, 2012 at 20:24 Comment(2)
I have gone through the recommended records but no luck. Can you be kind to share your answerShainashaine
@Vezu check out the new answer.Handmaid
K
10

As others have said, you need to utilize the ApplicationController's before_filter. Though ernie himself seems not to recommend this, the implementation is simple.

First, use the advanced Ransack options to set your path for your search thusly

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

Second, update your BucketsController to include the following custom action:

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

Nothing yet out of the ordinary. If you currently try to search you will get the error from your original question. Your definition of the variable q is correctly implemented, but you will have to move it to the ApplicationController like so:

#controllers/application_controller.rb
before_filter :set_global_search_variable

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

Finally, update your search form to pass in the correct search options

#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 %>
Karlykarlyn answered 12/11, 2013 at 12:51 Comment(1)
Works. This way, the search url goes as my-rails-app.com/buckets/searchNorthampton
C
1

No, you do not need to edit all your controllers.

You can use ApplicationController for all your "common" controller needs. Read up on it in the guides http://guides.rubyonrails.org/action_controller_overview.html and the API docs http://api.rubyonrails.org/classes/ActionController/Base.html

The key here is, when you generated your new rails app, you'll notice it created the file .../app/controllers/action_controller.rb and that class derives from ActionController::Base. Then, if you again use the rails generator to create a controller for your app, you'll notice your new controller class derives from ApplicationController (not ::Base). That means that the application_controller.rb is the parent controller class for your app. That means everything in it is available to all your app controllers. It's easy to abuse, so be judicious.

Cyndy answered 10/5, 2012 at 11:40 Comment(0)
S
1

Looks like this is not possible. This is a comment from Ernie the gem author.

You'd have to handle the Ransack-required stuff in a before_filter or (ick) in the view partial itself. If you're putting a search field on every single part of the site, I'd recommend you strongly consider whether ransack is the right tool for the job, as well. You might want some sort of inverted index search setup like sphinx, solr, etc.

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

Shainashaine answered 17/11, 2012 at 19:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.