simple rails search form not working - ruby-on-rails

I have a very simple, typical search form in rails. Input a string, and it checks a column for that model if any strings match it. A few weeks ago it was working just fine. I came back today, and suddenly doesn't work.
Here is my code. My search form:
<%= form_tag("/search/products", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
My Controller:
def search
term = params[:q]
puts "the term is #{term}"
#resultats = Product.search_products(term)
end
In my model, the search_products method:
def self.search_products(search_term)
if search_term == ""
return []
else
where("name LIKE ?", "%#{search_term}")
end
end
in the controller code, the puts "the term is #{term} prints the correct term every time. So I know that is being picked up correctly. just, when i search for something, it doesn't return the correct results. Here is a screenshot from my terminal:
"Les résultats sont" in the terminal means "the results are..." and then empty, because it returns nothing. What could be wrong here?

Your code currently searches for LIKE '%term' (string must end in term)
You probably need to have it search for LIKE '%term%' (string must contain term)
Just add a %:
where("name LIKE ?", "%#{search_term}%")

Why don't you do lower(?) and search_term.downcase to make sure its not case sensitive

Related

Simple search form is not working in rails

I'm following Railscast: http://railscasts.com/episodes/37-simple-search-form?autoplay=true
The result shows well in my implementation. But because I have first_name and last_name columns instead of just "name" as in the example above, I need a way to search for both no matter what the search term is. How can I do this? Right now only first name search works.
user.rb
def self.search(search)
if search
where('first_name LIKE :search OR last_name LIKE :search', search: "%#{search}%")
else
all
end
end
people_controller, index function:
#users = User.search(params[:search])
index.html.erb (for people controller):
<%= form_tag people_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag("Search users", first_name: nil, last_name: nil) %>
</p>
<% end %>
<ul>
<% #users.each do |user| %>
<li>
<%= link_to profiles_path(user_id: user.id) do %>
<%= user.first_name %>
<%= user.last_name %>
<% end %>
</li>
<% end %>
</ul>
UPDATE:
So this is weird. I have 4 users. For the first 3, only first name search works. Last name or full name (or partial name) doesn't. For the last user, only last name search works.
...what could be going on? Just made three more users and tested. The first new user got searched only by first name. The second new user got searched by only last name. His first name is part of the last name of 3rd user, and that 3rd original user name was returned when searched by that new user's first name (...why? didn't work like this before; partial name search doesn't work for other users). And third user's last name only was searched.
UPDATE:
OK, didn't do anything. But now the first original's user gets searched by either last name or first name (only first name before). WHY? Second original user as well. And partial search for two users works now. WHY? And the last new user whose last name (only) was searchable is now not searchable by any. WHY?
And tried it again just now and returned to previous, searchable by first name only, no partial search, etc. Why is this keep changing? How can I make the search term simply search for either first name or last name or both?
UPDATE:
I got the answer (to the above, not in general). The search is CASE-SENSITIVE. Now my question is: how can I make it non-case-sensitive and have the search term that includes both first name and last name (eg "Tom Paulson") work? (right now only searching for either works)
UPDATE:
So I solved case sensitivity by changing LIKE to ILIKE. I'm using Postgres.
If you could help with searching for both first name and last name, I'd appreciate it!
UPDATE:
So I'm now using this to search for both or either first name and last name. But now partial search does not work. Is there a way to make that work here as well?
where("first_name ilike :search or last_name ilike :search or first_name || ' ' || last_name ilike :search", search: "%#{search}")
UPDATE:
Solved it by adding % to %#{search}
%#{search}%
The case seems resolved. Thank you! I will maybe post an answer later.
UPDATE:
ooh, you wanted to search in both columns.
one way is to use 'concat'.
assuming you put a space in between first and last name:
where("CONCAT(first_name, ' ', last_name ) ILIKE ?","%#{search}%")
FIRST ANSWER:
def self.search(search)
if search
buff=search.downcase
where('lower(first_name) LIKE ? OR lower(last_name) LIKE ?', "%#{buff}%", "%#{buff}%")
should be working.
or ILIKE if you prefer.
where('first_name ILIKE ? OR last_name ILIKE ?', "%#{search}%", "%#{search}%")
can you check the value of 'params[:search]' if it is not nil?

combine two search results ruby on rails

I am trying to have two search fields, that however end up combining the two results.
In one filed you can search for the location of a listing and in the other for a keyword, which will look for title and description of the listing.
When a location and keyword is entered, listings that match both the location and keyword should show. So if I enter San Francisco and Retail, only listings located in SF and with the description or title Retail should pop up.
Feng Chen suggested to do this in one query by the following:
self.where("location like ? and (title like ? or description like ?)", query, query)
However this does not show a result that matches both the location and the keyword(title, description).
Do I need to change something in my view or anywhere else?
Here is what I have listing.rb
def self.locsearch(search)
query = "%#{search}%"
if search
self.where("location like ? and (title like ? or description like ?)", query, query)
else
self.all
end
end
end
Static_pages_controller.rb
def home
#listings = #listings.locsearch(params[:search]) if params[:search].present?
home.html.erb
<%= form_tag findjobs_path, :controller => 'listings', :action => 'locsearch', :method => 'get' do %>
<p>
<%= text_field_tag :search, "location" %>
<%= text_field_tag :search, "keyword" %>
<%= submit_tag "search" %>
</p>
</div>
<% end %>
You need a descsearch method in your listing model and you need to do
# Right now you have #listings = #listings.locsearch(...)
# You need #listings = Listing.locsearch(...)
#listings = Listing.locsearch(params[:search][:location], params[:search][:keyword])
And in your listing model
def self.locsearch(location, keyword)
location = "%#{location}%"
keyword = "%#{keyword}%"
if !location.bllank? && !keyword.blank?
self.where("location like ? and (title like ? or description like ?)", location, keyword)
else
self.all
end
end
end
If you are using a postgres database, you could try to use the full text search feature to do the above. There is gem pg_search enter link description herewhich will allow you to do so easily. The overhead incurred would be trivial and would provide you greater flexibility in this search problem and any such other ones you might have to solve later.

Rails Search result issue

I am trying to create a search function in Rails 4. I have it implemented properly and it is displaying the result I want, however it is also returning and displaying the entire database query - All columns from table including password digest etc. I have done this before but haven't run into an issue like this. Would like to know if I am doing something wrong.
here is my controller:
def index
if params[:search]
#pro = Admin.search(params[:search])
else
#pro = Admin.all
end
end
Admin Model:
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
scoped
end
end
And here is my views:
<%= #pro.each do |ind| %>
<ul>
<li><%= ind.name %></li>
</ul>
<% end %>
in Chrome, I see the returned name of the individual from the search, as I would like, plus meta data such as id: 1, admin_id: 2, name "", email: "", password_digest: "" etc. in an array format. This is what's stumping me, not sure why it's displaying this.
When I inspect the page in chrome, the array is just pasted right under the tags.
It goes away when I remove the entire .each method on #pro. Any insight anyone can provide is appreciated.
The line in view should be <% #pro.each do |ind| %>. If you're doing <%= %> the result is the actual #pro array, which is why you're getting it pasted under the tags.

Building a selectbox or filter in Rails

Hi maybe this is a fool question, but i really try to look couldnt find any relevant info, (maybe cause i dont know where exactly to start looking at) ..
I need to build a select box with options so the user can "filter" by the candidate.poisition value i have. at this moment the view has this code..
I was thingin on using :params, to post them in URL (i have always do php, im doing rails cause my task now is to insert a design, i achieve everything, just missing a selectbox filter)
Anyway.. here is the code.. wich is pretty simple
<% #candidates.each do |candidate| %>
<% if (candidate.active == true) && (candidate.position.present?) %>
All the html code with info.. like
<%= candidate.name %> : <%= candidate.position? ? t('generales.'+candidate.position) : t('activerecord.models.elite') %>
<% end %>
<% end %>
how can i make this , as im really a noob in Rails, im a regular user on PHP not even really good jaja, pls, i hope someone can give me a hand on this.
Can I use something like this : How to do a LIKE query in Arel and Rails?
Like candidates.where("position like '%?%'", params[:query]).to_sql
Also how can i build the Post as you do in PHP , no idea, to change the position that you want to filter.
Model Candidate.rb just have this inside :S
class Candidate < ActiveRecord::Base
end
Basically you're right. Here is improved code:
<% #candidates.each do |candidate| %>
<% if candidate.active && candidate.position.present? %>
<%= candidate.name %> : <%= t("generales.#{candidate.position}") %>
<% end %>
<% end %>
Update per request in comments:
Use code like this in controller:
if params[:position] == 'red'
#candidates = #candidates.where(position: 'red')
elsif params[:position] == 'blue'
#candidates = #candidates.where(position: 'blue')
else
#candidates = Candidate.all
end
and build html form that will pass parameter position.
or you can use https://github.com/activerecord-hackery/ransack

Alphabet Filter for Table in Rails

I'm new to rails, so forgive me if there is an easy answer. I'm trying to implement an "Alphabet Index" for a table in rails. I want to be able to click on a letter and have the table refresh - containing only the data on which the first letter of the last_name column matches the letter clicked.
My first thought was to generate an array of letter from the database
#visitor_array = []
#v = Visitor.all
#v.each do |visitor|
#visitor_array << visitor.last_name[0,1]
end
#visitor_array.sort!
#visitor_array.uniq!
This code gives me an array which has one of each of the first letters. I used this as my "alphabet". On my view I have the following code
<% #visitor_array.each do |visitor| %>
<%= link_to visitor, alphasort(visitor) %>
<% end %>
The thought here is to run a helper function when the letter is clicked. But here is where I'm stuck.
UPDATE:
Okay, thanks to the comments below, I was able to figure it out. In case anyone else was wondering, this is how it was accomplished.
CONTROLLER
# Create array consisting of the first letter of every visitor's last name
#visitor_array = []
#v = Visitor.all
#v.each do |visitor|
#visitor_array << visitor.last_name[0,1]
end
#Sort array alphabetically in ASC order
#visitor_array.sort!
#Remove duplicate elements
#visitor_array.uniq!
if (params[:letter] != nil)
#visitors = Visitor.order("last_name ASC").where("last_name like ?", params[:letter] +"%" )
else
#visitors = Visitor.order("last_name ASC")
end
VIEW
<% #visitor_array.each do |letter| %>
<%= link_to letter, :controller => "visitors" , :letter => letter %>
<% end %>
Use this to get the list of results for a specific letter:
visitors = Visitor.order("last_name ASC").where("last_name like '?'", letter)
Then on your view:
<% #visitor_array.each do |visitor| %>
<%= link_to visitor(visitor) %>
<% end %>
The syntax might be slightly off but the fundamental idea is there.
I'm not entirely sure what you mean by the last line though...

Resources