How to use like clause query in rails? - ruby-on-rails

I wanted to get a json format of the data when searching for the keyword so I use LIKE clause and query like this
"select * from employees where fname like ? or mname like ? or lname like ? or username like ? or id like ?", str, str, str, str, str
but I want to code it using rails. I have this code in my controller
def showemployees
str = params[:str]
render json: #employee = Employee.where(Employee.employees[:fname].matches("%#{str}%")) or
(Employee.employees[:mname].matches("%#{str}%")) or
(Employee.employees[:lname].matches("%#{str}%")) or
(Employee.employees[:id].matches("%#{str}%"))
end
and this code in my config/routes.rb
get 'employees/showemployees'
root :to => 'employees#new'
resources :employees
post 'employees/update_info'
when i type this, http://localhost:3000/employees/showemployees?str=samplename, a json format of the record should appear yet I got this error message
undefined method `employees' for #<Class:0x8e38900>
app/controllers/employees_controller.rb:6:in `showemployees'
where line 6 has this code
render json: #employee = Employee.where(Employee.employees[:fname].matches("%#{str}%")) or

You can chain where queries, but this AND each where query results
Employee.where('fname LIKE ?', "%#{str}%").where('lname LIKE ?', "%#{str}%").where('mname LIKE ?', "%#{str}%").where('username LIKE ?', "%#{str}%").where('id LIKE ?', "%#{str}%")
or to use OR clause
Employee.where('fname LIKE ? OR lname LIKE ? OR mname', "%#{str}%", "%#{str}%", "%#{str}%")

Related

Search for item name from multiple fields on Ruby on Rails

I'm trying to enable a search for an item, and then have that item listed if the search is completed. I can get it to work for both instances, but not at the same time. My code:
def search
#results=0
if !params[:searchinput].empty?
#results=1
#searchinput = params[:searchinput]
#searchcriteria="%#{params[:searchinput]}%"
#productlist = Product.where("productname like ? OR description like ?", #searchcriteria)
end
end
I get the following error:
Is the formatting with the productlist statement wrong?
The problem is you have to pass in two variables. If that is #searchcriteria then pass that in.
def search
#results=0
if !params[:searchinput].empty?
#results=1
#searchinput = params[:searchinput]
#searchcriteria="%#{params[:searchinput]}%"
#productlist = Product.where("productname like ? OR description like ?", #searchcriteria, #second_variable)
end
end
the productlist statement should look like the following:
#productlist = Product.where("productname like ? OR description like ?", #searchcriteria, #searchcriteria)

Ignore uppercase, downcase and accent in search

I have a search system with filter here. This system work like a charm but I have some problem with downcase / uppercase and accent.
For example if I search "marée" I have result but if I search "MAREE" or "Marée" or "maree". I don't have result.
I want to fix that. How I can fix this ? Thank you.
my controller
def resultnohome
if params[:query].blank?
redirect_to action: :index and return
else
#campings = Camping.searchi(params[:query], params[:handicap], params[:animaux], params[:television], params[:plage], params[:etang], params[:lac])
if params[:query] == "aube"
#pub = Camping.find_by_id(1)
else
end
end
end
My model
def self.searchi(query, handicap, animaux, television, plage, etang, lac)
return scoped unless query.present?
result = left_outer_joins(:caracteristiquetests, :situations).where('nomdep LIKE ? OR name LIKE ? OR nomregion LIKE ? OR commune LIKE?', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%")
result = result.where('handicap LIKE ?', "%#{handicap}%") if handicap
result = result.where('animaux LIKE ?', "%#{animaux}%") if animaux
result = result.where('television LIKE ?', "%#{television}%") if television
result = result.where('plage LIKE ?', "%#{plage}%") if plage
result = result.where('etang LIKE ?', "%#{etang}%") if etang
result = result.where('lac LIKE ?', "%#{lac}%") if lac
return result
end
If you insist on using SQLite then you don't have many good options. The most common suggestion is to have extra columns in your database, that are normalized values so if your plage column contains "Marée" then you also have a column plage_ascii that contains "maree"
you need to create the additional columns with migrations, then you would have a before_save action in your model...
before_save :create_normalized_strings
def create_normalized_strings
self.handicap_ascii = handicap.downcase.mb_chars.normalize(:kd).gsub(/[^x00-\x7F]/n, '').to_s
self.animaux_ascii = animaux.downcase.mb_chars.normalize(:kd).gsub(/[^x00-\x7F]/n, '').to_s
# etc etc
end
Then in your search do...
if handicap
test_handicap = handicap.downcase.mb_chars.normalize(:kd).gsub(/[^x00-\x7F]/n, '').to_s
result = result.where('handicap_ascii LIKE ?', "%#{handicap}%")
end
It's not great, as it basically forces you to duplicate data in your database into extra columns. If you can consider more sophisticated databases other than SQLite then you'd be better off... personally I wouldn't ever use SQLite in a production environment.

Search every field or attribute in model Rails

I have a simple model called Company with atributes such as Name, contact email, address, etc. I've created a search form where a user can find the company by searching for any attribute i.e., city, name of business, etc.
I'm new to Rails but I've figured out how to get it working like so in my controller.
if(params[:searchstring].present?)
logger.debug "*** Running search --> "
term = params[:searchstring]
#companies = Company.where('name LIKE ? OR name LIKE ? OR contactemail LIKE ? OR city LIKE ?' , "%#{term}%", "%#{term}%", "%#{term}%","%#{term}%" ).paginate(page: params[:page]).order('id DESC')
else
logger.debug "*** Running search --> get em all "
#companies = Company.all.paginate(page: params[:page], per_page: 5).order('id DESC')
end
end
This works fine but I'm guessing there is a much simplier way. I'd prefer not to modify the query every time I add an attribute. Any ideas on how to improve this?
You could go with something like this (It is just an example, might be a better way, but it is fonctionnal)
# company.rb
def self.search_all_properties term
query = ''
properties = Company.column_names
properties.each_with_index do |prop, index|
if index < properties.count - 1
query = query + prop + ' LIKE :term OR '
else
query = query + prop + ' LIKE :term'
end
end
term = "%" + term + "%"
Company.where(query, :term => term)
end
and use it like this
Company.search_all_properties term

Pulling unique case-insensitive values

I'm using jQuery autocomplete in a few areas. It makes a call to this method:
def index
#schools = School.order(:name).where("name like ?", "%#{params[:term]}%").limit(10)
render json: #schools.map(&:name)
end
Initially I didn't handle case sensitivity well, so I have some duplicate names in differing cases (ie. "Rutgers" and "rutgers".
I'd like to change the above method to return only unique values, ignoring the case, so only one "Rutgers" result will be returned.
I'm going to clean up the DB but a quick temp fix for this would be great!
I guess it depends on which DB you are using, but you can try doing something like this:
def index
#school_names = School.order("lower(name)")
.where("name ilike ?", "%#{params[:term]}%")
.distinct.limit(10).pluck("lower(name)")
render json: #school_names.map(&:downcase)
end
The above will work with POSTGRESQL, for Sqlite, this will work:
def index
#school_names = School.order("lower(name)")
.where("lower(name) LIKE lower(?)", "%#{params[:term]}%")
.distinct.limit(10).pluck("lower(name)")
render json: #school_names.map(&:downcase)
end

Search through sentences

I have a rails app and have decided to have a search. I have a search textfield and the controller takes care of everything. In my search method
def self.search(search)
if search
str = []
search.split.each do |s|
a = find(:all, :conditions => ['title or content LIKE ?', "%#{s}%" ])
str = (str + a).uniq
end
else
find(:all)
end
end
I want to be able to handle multiple word searches. If you remove the each...loop it works fine with 1 word searches.
Anyways, I would like to find the related posts for each word that is searched and return a combination of that.
Ex. If someone searches "Greatest Player" it will return all instances of posts that have the title or content "Greatest" and any that have the title or content "Player"
You most likely should be looking at full text searching:
Full Text Searching with Rails
http://en.wikipedia.org/wiki/Full_text_search
Shouldn't it be
a = find(:all, :conditions => ['title or content LIKE ?', "%#{s}%" ])
All you needed was to change the find statement to Mischa's code and add a return statement
Working Code:
def self.search(search)
if search
str = []
search.split.each do |s|
a = where(title LIKE ? or content LIKE ?', "%#{s}%", "%#{s}%")
str = (str + a).uniq
end
return str
else
find(:all)
end
end

Resources