I'm making a search-function in a Rails project with Postgres as db.
Here's my code
def self.search(search)
if search
find(:all, :conditions => ["LOWER(name) LIKE LOWER(?) OR LOWER(city) LIKE LOWER(?) OR LOWER(address) LIKE LOWER(?) OR (venue_type) LIKE (?)", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%"])
else
find(:all)
end
end
But my problem is that "venue_type" is an integer. I've made a case switch for venue_type
def venue_type_check
case self.venue_type
when 1
"Pub"
when 2
"Nattklubb"
end
end
Now to my question: How can I find something in my query when venue_type is an int?
Please try this code. Here I have added switch case to where clause.
def self.search(search)
if search
find(:all, :conditions => ["LOWER(name) LIKE LOWER(?) OR LOWER(city) LIKE LOWER(?) OR LOWER(address) LIKE LOWER(?) OR (venue_type = CASE WHEN 'pub' = ? THEN 1 WHEN 'nattklubb' = ? THEN 2 END)", "%#{search}%", "%#{search}%", "%#{search}%", "#{search.downcase}", "#{search.downcase}"])
else
find(:all)
end
end
I think you have to use if-else condition in your where clause something like following
find(:all, :conditions => ["LOWER(name) LIKE LOWER(?) OR LOWER(city) LIKE LOWER(?)
OR LOWER(address) LIKE LOWER(?) OR
IF(venue_type == 1, 'Pub', IF(venue_type == 2, 'Nattklubb2', '')) LIKE (?)",
"%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%"])
If you are using rails 3.2 or greater, you should use where( [] ) instead for find.
where( [ "field like ?", field ] ).order(). ...
Also, when using pgsql why are you not using ilike instead of like with lower?
In your case while searching int or not int, I would use different queries.
When search.to_i != 0
Related
I'm using a LIKE clause in Ruby On Rails. When I try to search for records by typing "more" it doesn't return anything, but when I do with "More", then it returns the records which contains More keyword, so it seems like it behaves in a case-sensitive way.
Is it possible to make this case-insensitive?
Here is the query I am using currently:
Job.where('title LIKE ? OR duration LIKE ?', "%#{params[:search]}%", "%#{params[:search]}%")
I assume you're using Postgres.
You can use ILIKE
Job.where('title ILIKE ? OR duration ILIKE ?', "%#{params[:search]}%", "%#{params[:search]}%")
Or a some tricky hack lower():
Job.where('lower(title) LIKE lower(?) OR lower(duration) LIKE lower(?)', "%#{params[:search]}%", "%#{params[:search]}%")
try something like this
def query_job(query)
job_query = "%#{query.downcase}%"
Job.where("lower(title) LIKE ? or lower(duration) LIKE ?", job_query, job_query)
end
query_job(params[:search])
I'm using a LIKE clause in Ruby On Rails. When I try to search for records by typing "more" it doesn't return anything, but when I do with "More", then it returns the records which contains More keyword, so it seems like it behaves in a case-sensitive way.
Is it possible to make this case-insensitive?
Here is the query I am using currently:
Job.where('title LIKE ? OR duration LIKE ?', "%#{params[:search]}%", "%#{params[:search]}%")
I assume you're using Postgres.
You can use ILIKE
Job.where('title ILIKE ? OR duration ILIKE ?', "%#{params[:search]}%", "%#{params[:search]}%")
Or a some tricky hack lower():
Job.where('lower(title) LIKE lower(?) OR lower(duration) LIKE lower(?)', "%#{params[:search]}%", "%#{params[:search]}%")
try something like this
def query_job(query)
job_query = "%#{query.downcase}%"
Job.where("lower(title) LIKE ? or lower(duration) LIKE ?", job_query, job_query)
end
query_job(params[:search])
In my application I have a customers model with three columns, first_name, middle_name and last_name. I have a method in the model that performs the search:
class Customer < ActiveRecord::Base
belongs_to :user
def self.search(search, user)
if search
.where('first_name LIKE ? OR middle_name LIKE ? OR last_name LIKE ?', "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%")
.where(user: user)
else
where(user: user)
end
end
end
The problem with this search function is that it only allows searching by one of the three columns at a time.
For example, a customer has a first_name of "foo", a middle_name of "bar" and a last_name of "baz". Searching for "foo", "bar", or "baz" individually returns results, but "foo bar" or "bar baz" does not.
What is the best way I can allow searching across all three columns?
You can concat your fields in the database query like
Updated:
.where("concat_ws(' ' , first_name, middle_name, last_name) LIKE ?", "%#{search}%")
This should work for foo, foo bar, or foo bar baz
but not foo baz
If you want to support foo baz as well then
.where("first_name LIKE ? OR middle_name LIKE ?"\
" OR last_name LIKE ? OR concat_ws(' ' , first_name, middle_name, last_name) LIKE ?"\
" OR concat_ws(' ' , first_name, last_name) LIKE ?",
"%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%")
.where("first_name LIKE ? OR middle_name LIKE ? OR last_name LIKE ? or CONCAT(first_name, middle_name, last_name) LIKE ?", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%")
If you use pg, you can try like this
def self.search(query)
where(['phone ilike :query',
'LOWER(name) ilike :query',
'LOWER(email) ilike :query',
'LOWER(address) ilike :query'].join(' OR '), {query: "%#{query}%" })
end
I am working in an app with a basic search form with Heroku, but I can't get my sql query to work properly with PostgreSQL, even though this query worked with MySQL. By the way, I tried to paste the logs from Heroku, but it only says that when you search something it renders 500.html.
Here's my model OrdemDeServico with the search action:
def self.search(search)
if search
joins(:cliente).where("clientes.nome LIKE ? OR veiculo LIKE ? OR placa LIKE ? OR ordem_de_servicos.id = ?", "%#{search}%", "%#{search}%", "%#{search}%", "#{search}")
else
where(nil)
end
end
I just installed PostgreSQL locally, and it returned this error when searching:
`PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "Augusto"
LINE 1: ... placa LIKE '%Augusto%' OR ordem_de_servicos.id = 'Augusto')
query:
SELECT "ordem_de_servicos".* FROM "ordem_de_servicos" INNER JOIN "clientes" ON "clientes"."id" = "ordem_de_servicos"."cliente_id" WHERE (clientes.nome LIKE '%Augusto%' OR veiculo LIKE '%Augusto%' OR placa LIKE '%Augusto%' OR ordem_de_servicos.id = 'Augusto') ORDER BY prazo LIMIT 5 OFFSET 0
I finally worked it out a solution. Those who have the same problem here's my code for the model:
def self.search(search)
if search
where("id = ?", search)
joins(:cliente).where("clientes.nome ilike :q or veiculo ilike :q or placa ilike :q", q: "%#{search}%")
else
where(nil)
end
end
I was really happy using this query for the search form. However, just found out that is not working properly.
The failing bit is the .where which like against params[:query]. This like happens 4 times against 4 different fields. However, results shows that this is not happening.
#events_casual = Event.non_timetable.where("events.finish_date >= ?", #time).where((["CAST(headers.title_es as varchar(255)) LIKE ?", "%#{params[:query]}%"] || ["CAST(headers.title_en as varchar(255)) LIKE ?", "%#{params[:query]}%"] || ["CAST(headers.title_eu as varchar(255)) LIKE ?", "%#{params[:query]}%"] || ["CAST(headers.title_fr as varchar(255)) LIKE ?", "%#{params[:query]}%"])).includes(:header).order("events.start_date ASC")
I have been trying to transform this query into:
#events_casual = Event.non_timetable.joins(:header).where(" params[:query] in (?)", [headers.title_es, headers.title_en, headers.title_eu]).order("events.start_date ASC")
But, this does not work. Error: undefined methodtitle_es' for {}:Hash`
I have tried similar syntax. But to not avail.
Any help rewriting that query much appreciated. Thanks
try the following
#events_casual = Event
.non_timetable
.includes(:header)
.order("events.start_date ASC")
.where("events.finish_date >= ?", #time)
.where("CAST(headers.title_es as varchar(255)) LIKE :query OR CAST(headers.title_en as varchar(255)) LIKE :query OR CAST(headers.title_eu as varchar(255)) LIKE :query OR CAST(headers.title_fr as varchar(255)) LIKE :query", { query: "%#{params[:query]}%"])