Using ransack to search from different controller action - ruby-on-rails

I have a PagesController that contains two actions
def search
#q = Listing.ransack(params[:q])
#listings = #q.result(distinct: true)
#listings = #listings.where(active: true).order("created_at DESC").page(params[:page]).per(12)
end
and
def home
end
now what I would like to achieve is that I could fire a search from the home path to the search path like
home.html.erb
<%= search_form_for #q, url: search_path do |f| %>
<%= f.search_field :listing_name_cont %>
<%= f.submit 'Search' %>
but this returns No Ransack Search object was provided to search_form_for which It should since there is no q param passed to the home action. The only way I can get this to work is that if I modify the home action as follows
def home
#q = Listing.ransack(params[:q])
end
but this doesn't seem reasonable since I'm not displaying any of the listings on the home page so I can imagine this will just slow down the page by quite a lot If I'm fetching a lot of listings. Is there any other way I could achieve this?

You can do <%= search_form_for #q, url: 'home' do |f| %>
'home' can be whatever you want the URL extension to be.

Related

Ransack Search model attributes from different controller

I have a Rails App going here and I am building ransack into it.
I Have Devise installed, but really have no use for a user index page, instead I have a controller named MemberListController with directory method in it and a directory page that links to it. This is where I want my admin users to view the membership directory. (see below for controller)
MemberListController.rb
class MemberListController < ApplicationController
before_action :authenticate_user!
def directory
#users = User.all
#q = User.ransack(params[:q])
#user = #q.result(distinct: true)
respond_to do |format|
format.html
format.xlsx
end
end
end
I built in the following search form to the directory page:
<%= search_form_for #q do |f| %>
<%= f.label :f_name_or_l_name_or_email_or_business_name %>
<%= f.search_field :f_name_or_l_name_or_email_or_business_name %>
<%= f.submit %>
<% end %>
When I submit the form from the directory page (where i want the results to be displayed.. I get the following error:
UsersController#index is missing a template for this request format and variant. request.formats: ["text/html"] request.variant: [] NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.
Im not sure why i twats a user controller or index action as everything is managed through the directory controller.
Please help not sure where I'm going wrong with this.. is there a way to display this out side of the users controller like ransack wants to?
Ransack is smart enough to infer form_url from ransack search object.
So, if you don't pass any url option to ransack search_form_for it will submit the form to index action of the entity for which ransack search form is built.
So, you have to change your view logic to the following code-
<%= search_form_for #q, url: member_lists_path do |f| %>
<%= f.label :f_name_or_l_name_or_email_or_business_name %>
<%= f.search_field :f_name_or_l_name_or_email_or_business_name %>
<%= f.submit %>
<% end %>
Here, you can read more about ransack.

Creating site-wide search in a Rails app

I'm trying to create a search form that retrieves results based on a user's query for a restaurant's name. So far I've setup its route, controller, and index view.
routes.rb
resources :search, :only => [:index]
search_controller.rb
class SearchController < ApplicationController
def index
if params[:query].present?
#restaurants = Restaurant.search(params[:query])
else
#restaurants = Restaurant.all
end
end
end
search/index.html.erb
<% #restaurants.each do |restaurant| %>
<%= restaurant.name %>
<% end %>
Here is how the search for is setup:
layouts/_header.html.erb
<%= form_for search_index_path, method: :get do |f| %>
<%= text_field_tag :query, params[:query] %>
<%= submit_tag "Search", name: nil %>
<% end %>
Right now I'm running into two problems. The first being that if I enter a query and submit, the page doesn't go to the index page. All it does is append the query to the current page I'm on:
localhot:3000/restaurant?utf8=✓&query=pizza
Second is that I'm getting every restaurant in my db on the index page (as expected). Is there a way that I can make it so the page is blank for anything other than on search requests?
Question 1
Use form_tag instead of form_for, since the latter is used to handle specific model objects and this is not the case.
Question 2
You can achieve that by:
if params[:query].present?
#restaurants = Restaurant.search(params[:query])
else
#restaurants = [] # or Restaurant.none if you need a chainable scope
end

Show Ransack search results on different page

I am using Ransack to add a simple search form on my homepage. I would like the results of the search to show on a different page, instead of on the homepage.
The HomeController has an index action with the #search variable set as follows
def index
#search = User.search(params[:q])
#users = #search.result
end
The view contains
<%= search_form_for #search do |f| %>
<fieldset>
<legend>User</legend>
<ul>
<li>
<%= f.label :first_name_or_last_name_cont %>
<%= f.text_field :first_name_or_last_name_cont %>
</li>
<li>
<%= f.label :email_cont %>
<%= f.text_field :email_cont %>
</li>
</ul>
</fieldset>
<fieldset>
<legend>User's Posts</legend>
<ul>
<li>
<%= f.label :posts_title_cont %>
<%= f.text_field :posts_title_cont %>
</li>
</ul>
</fieldset>
<%= f.submit %>
<% end %>
<%= render 'results' %>
How can I set up the controller so that I can use <%= render 'results' %> in a different view for a different action, say a search action? How can I do this so that when I submit the search form I am directed to a new page for the search action which displays the search results?
Great question! To answer your question, you can create a private method with a redirect_to a different page (that has <%=render 'results' %>) IF search params are passed in your HomeController.
class HomeController < ApplicationController
before_action :search
def index
#search = User.search(params[:q])
#users = #search.result
end
private
def search
if params[:q]
search_params = CGI::escapeHTML(params[:q])
redirect_to (url --> see below how to get the url)
end
end
end
However, if you want to start building out your app, you want your search results to display on that dedicated page, no matter where you are at in the app. I am pasting in a full answer from a small rails app. The code is only slightly different (form_tag instead of search_form_for), but I know it works, so hopefully it will help you.
Below, is a nav bar partial that is displayed across the app and then the relevant code for the home page and the ListingController index action. If search params are passed, then index.html.erb renders the #listings partial (_listing.html.erb) and nothing below the <% else %> tag on the home page.
_navigation.html.erb
<%= form_tag search_path, :method => :get do %>
<div class="form-group">
<%= text_field_tag :search, params[:search], class: "form-control", placeholder: "Search" %>
</div>
<%= submit_tag "Submit", :name => nil, :class => "btn btn-primary" %>
<% end %>
index.html.erb
<% if params[:search] %>
<h2>Search Results</h2>
<%= render #listings %>
<% else %>
...what usually shows up on my home page with no search results.
<% end %>
listings_controller
def index
#listings = Listing.search(params[:search])
end
routes.rb
get 'search' => "listings#search"
This works great. However, if I am in a different view/controller, like the one showing all the categories, and try to search, then it basically searches the current page. So, I added the following to the categories controller:
categories_controller
before_action :search
......
private
def search
if params[:search]
search_params = CGI::escapeHTML(params[:search])
redirect_to ("/listings?utf8=%E2%9C%93&search=#{search_params}")
end
end
BUT, for your specific app, to get the search to redirect to the home page and display the search results, first do a search on your home page and see what is generated in the url. Let's say I typed 'cheese' (/listings?utf8=%E2%9C%93&search=cheese). Notice the %E2%9C%93...you may not see this b/c this normally displays as a check in the url on your browser (http://unicode-search.net/unicode-namesearch.pl?term=mark)...so just paste it into text wrangler or stackoverflow text area to get the 'full url' like above. Then at the end of the url, just replace what you typed into the search box with #{search_params}.
This passes whatever was typed into the search box to your dedicated search results page (in my case index.html.erb)!
Here is some documentation on CGI escapeHTML (for security reasons): http://ruby-doc.org/stdlib-2.0/libdoc/cgi/rdoc/CGI.html#method-c-escapeHTML

Working with Third party yummly api in rails 4

I've searched all over the web for decent explanations of how to do what I want to do, but cannot find any.
What I want to do is have the user be able to search through the yummly api and return some results back...
Here is some code.
index.html.erb
<% #results.each do |r| %>
<%= r.name %>
<% end %>
home_controller.rb
class HomeController < ApplicationController
def index
#results = Yummly.search('Onion')
#recipe = #results.map(&:to_s)
end
end
I've installed the Yummly gem which allows me to call Yummly.search
How can I allow the user to search for the term instead of hard coding it? It returns just fine hard coded but I cannot figure out how to allow the user to search.
Thank you!
Ideally, you would have a form that allows the user to enter a search term, and then pass that term to the Yummly API.
Something like (substitute your own route name):
<%= form_tag({controller: 'home', action: 'index'}, {method: :get}) do %>
<%= text_field_tag 'search' %>
<% end %>
And in your controller:
Yummly.search(params[:search])

rails search result

Now I can search only from videos page, How to add search from any page ot the site?
When I want to search from another controller search doesn't redirect to index
my controllers/videos_controller.rb
def index
#videos = Video.text_search(params[:query]).page(params[:page]).per(12)
end
my views/shared/_menu.html.erb
<%= form_tag videos_path, method: :get do %>
<%= search_field_tag :query, params[:query] %>
<% end %>
You can add that partial to any view page on the site (page_name.html.erb file). It will submit to the controller via the routes file.
Anywhere on the site you can add the following to a view:
<%= render "shared/menu" %>

Resources