Ok so i have a graphic model and I am using thinking sphinx as the search tool. It works well but i want to display different models on the search results page.. for example
i have this in my Graphic model
define_index do
indexes :name, :description, :scale,
indexes sub_category.name, :as => :subcategory_name
indexes sub_category.category.name, :as => :category_name
indexes colors.name, :as => :color_name
end
This is fine and good but the problem is i want to display all the categories and subcategories for a found search and not just the graphics that are related. In my controller should i have three find like
#graphics = Graphic.search params[:search]
#categories = Categories.search params[:search]
#sub_categories = SubCategories.search params[:search]
this seems like overkill...is there a better way so in the view i can show each of them seperately
You'll need to have indexes defined in your Category and SubCategory models as well, and then you can search across all three at once:
#results = ThinkingSphinx.search params[:search], :page => params[:page]
In your view, you'll want some logic around each search result to render the correct HTML - perhaps you can have different partials for each class? I'd also recommend wrapping it into a helper. Here's a start:
<ul>
<% #results.each do |result| %>
<li><%= render :partial => partial_for_search_result(result),
:locals => {:result => result} %></li>
<% end %>
</ul>
And the helper:
def partial_for_search_result(result)
case result
when Graphic
'graphics/search_result'
when Category
'categories/search_result'
when SubCategory
'sub_categories/search_result'
else
raise "Unknown search result/partial mapping for #{result.class}"
end
end
Hopefully this gives you some ideas on how to approach the problem.
Just to shorten example you can do:
in controller
#results = ThinkingSphinx.search params[:search], :page => params[:page]
in view
= render #results
should call every model partial 'graphic/_graphic.html.erb', 'categories/_category.html.erb' and so on
Related
I am creating a rails app where I have implemented the following search function.
application.html.erb
<div class="searchbar">
<%= form_tag(articles_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: " Search", :class => "search_form" %>
<%= submit_tag "Search", :name => nil %>
<% end %>
</div>
article.rb
def self.search(search)
where("title LIKE ? OR creator LIKE ? OR description LIKE ?", "%#{search}%", "%#{search}%", "%#{search}%")
end
articles_controller.rb
def index
#articles = Article.all
if params[:search]
#articles = Article.search(params[:search]).order("created_at DESC")
else
#articles = Article.all.order("created_at DESC")
end
end
This allows me to search for all primary resources but does not include nested resources in the search results. Is there a way to include these resources within the same function?
You'd need to do some joins, and define a syntax for passing the relevant join info into your search method.
This can get complicated pretty quick, and I'd highly suggest you don't reinvent the wheel and use an existing solution such as ransack. This will let you do things like
Article.ransack(title_cont: "code", author_name_cont: "bob").result
where, in this example, Author is its own model, associated with Article, and containing the field name.
It also plays very nice with views and forms, so you can very easily implement search forms without having the manually key everything up to the right association and field.
(Personally I'm not in love with their concatenation syntax but it gets the job done.)
At the moment I am trying to create a search within a project to bring up users depending on their region. From what I understand, I basically need to place the search params in the controller, the self.search method in the model, and then the form in the view.
In another project, I have a search but it shows all the options above and use the search to filter out those which do not match. For this situation, I do not want to list any users in the beginning. I want to use the search bar and bring up any users that match within that view page. Additionally I use Devise for users if that does make a difference. Here are my three regions of code:
Model (user.rb):
def self.search(search)
where("state ILIKE ?", "%#{search}%")
end
Controller (welcome_controller.rb):
def index
#users = User.all.order("created_at DESC")
#newusers = User.all.order("created_at DESC").limit(5)
#differentlocations = User.all.group_by(&:state).count
render :layout => 'with_newest_members'
if params[:search]
#users = User.search(params[:search]).order("created_at DESC")
else
#users = User.all.order('created_at DESC')
end
end
View (find.html.erb):
<%= form_tag(find_path, :method => "get") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search Posts" %>
<%= submit_tag "Search", :name => nil %>
<% end %>
Please let me know if you have any knowledge for me to help =) Any additional explanation would be greatly appreciated to help me understand, thank you!
Edit: I know I need to enter the results portion but I am confused about how/where to put it.
Joe
ANSWER:
The issue was in my controller because I had a render command prior to the search code. The controller should be:
def index
#users = User.all.order("created_at DESC")
#newusers = User.all.order("created_at DESC").limit(5)
#differentlocations = User.all.group_by(&:state).count
if params[:search]
#users = User.search(params[:search]).order("created_at DESC")
else
#users = User.all.order('created_at DESC')
end
render :layout => 'with_newest_members'
end
Fantastic =)
Two small things that might help:
1) In your Search model, I believe you have a typo in your search method. It should read as follows:
def self.search(search)
where("state LIKE ?", "%#{search}%")
end
You might also want to consider a more description name for your argument, such as state.
2) In your form, you don't need to explicitly write params[:search] anywhere. The params hash will be generated for you in the controller, with the name of the text_field as the key and the value inputted by the user as the value (see Ruby docs here). In this case, use :search as the name of the text_field_tag name.
<%= form_tag(find_path, :method => "get") do %>
<%= text_field_tag :search, placeholder: "Search Posts" %>
<%= submit_tag "Search", :name => nil %>
<% end %>
More on FormHelpers here.
I want to be able to search and update the index.
this is my controller method:
def index
if params[:search]
#ofertas = Oferta.search(params[:search]).paginate(page: params[:ofertas_page], :per_page => 5)
else
#ofertas = Oferta.all.paginate(page: params[:ofertas_page], :per_page => 5)
end
end
My search method in the model
def self.search(search)
where("titulo like ?","%w{search}%")
end
and this is the search form
<%= form_tag ofertas_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search], placeholder: "Procurar Entidades" %>
<%= submit_tag "Procurar", :name => nil %>
</p>
<% end %>
I've seen this setup in a number of search tutorials but no matter what I type nothing appears. Does someone know what I'm doing wrong?
It looks like you were trying to interpolate the search variable into the string, but didn't quite get the right symbol. How about this:
"%#{search}%"
Note the # instead of the w.
where("titulo like ?","%w{search}%")
should be:
where("titulo like ?", "%#{search}%")
#{xxx} is for string interpolation - it allows you to inject ruby (including variables) into a string.
"%xxxx%" is telling SQL that the search string can appear anywhere in the titulo column. '%' is a wildcard in SQL.
%w{xxx yyy zzz} is shorthand for ["xxx", "yyy", "zzz"] - an array in Ruby, which wouldn't mean much to the SQL as a string by itself.
I have a drop down list of Type in my Products model.
I want to be able to search in the Products index.html.erb so a user selects a type from a drop down list, clicks search and all the products matching that type are returned.
I can get normal search methods working where the user enters in their search in a text box but I cannot get it working when they just select from a dropdown.
Can anyone help?
In your controller :
def index
#products = Product.all :conditons => {:type => params[:type]}
end
In your view:
<% form_tag products_path, :method => :get do %>
<%=select_tag :type, options_for_select(Product::TYPES.map{ |type| [type, type]}), :onchange => "this.form.submit();" %>
<%=submit_tag "Search" %>
<% end %>
NB: The options_for_select accepts an array of pairs as [label, value], so we use map to build it.
I have a collection of people that is paginated with will_paginate
#people = Person.paginate :page => params[:page],
:limit => 10,
:conditions => ['company_id = ? ' , #company.id ]
The people are shown on the company/view page and rendered with a partial. Note that the partial is in the views of 'people'
<%= render :partial => "people/person" , :locals => { :people => #people }%>
in the partial ...
<% for person in #people %>
...
<%end%>
<%= will_paginate #people %>
Now the partial does work, it renders all of the people and shows the paginate links on the bottom. However it doesn't not actually paginate the collection and instead it shows everything on the first page.
I am clearly missing something rather basic.
Thanks in advance.
Are you missing per_page?
Per_page should be the problem.
Also make :page => params[:page] look like :page => params[:page] || 1 so that will_paginate will stop complaining on blank page parameters.