Ruby on Rails search method - ruby-on-rails

So I want to my user to be able to search by title and description so I have added this line of code.
Here is the error i receive
wrong number of bind variables (1 for 2) in: title LIKE ? or
description LIKE ?
def index
#posts = Post.where(["title LIKE ? or description LIKE ?", "%#{params[:search]}%"]).page(params[:page]).per(10)
end

You can name your arguments when you use the hash syntax - for example name it just :q:
#posts = Post
.where('title LIKE :q or description LIKE :q', q: "%#{params[:search]}%")
.page(params[:page]).per(10)

you're using two ? in this statement. so, the interpreter is expecting 2 arguments for each ?.
change your code to this:
#posts = Post.where("title LIKE ? OR description LIKE ?", "%#{params[:search]}%", "%#{params[:search]}%").page(params[:page]).per(10)
Let me know if it helps.

It's good practice to check Case insensitive matching
#posts = Post.where("LOWER(title) LIKE ? OR LOWER(description) LIKE ?", "%#{params[:search].downcase}%", "%#{params[:search].downcase}%").page(params[:page]).per(10)

You can also use this gem called ransack. Although is focused on forms, you can still make great simple search queries. See this documentation: https://github.com/activerecord-hackery/ransack/wiki/Basic-Searching

Related

Rails 4 search separate keywords with wrong number of bind variables (1 for 2)

I have this tentative search function, however, it is limited to search one chunk of keyword only.
def self.search(search)
search_condition = "%" + search + "%"
active.where("lower(title) LIKE ?", search_condition.downcase)
end
E.g. I have this title: "Peter Paul Mary"
If I search "peter Mary", it doesn't show.
I found this code useful in this post:
def self.search(search)
if search
search_length = search.split.length
find(:all, :conditions => [(['name LIKE ?'] * search_length).join(' AND ')] + search.split.map { |name| "%#{name}%" })
else
find(:all)
end
end
Unfortunately, it's in older rails.
So, how do I translate this into rails 4?
Update:
I've changed to something like this:
def self.search(str)
search = str.split.map{|w| "(lower(title) LIKE ? )"}.join(" OR ")
values = str.split.map{|w| "%#{w.downcase}%"}.map(&:inspect).join(', ')
.where("#{search}", values)
end
But it raises this error:
ActiveRecord::PreparedStatementInvalid (wrong number of bind variables (1 for 2) in: (lower(title) LIKE ? ) OR (lower(title) LIKE ? )):
Please advise.
If you happen to be using Postgres with your app, then you can easily take advantage of PG's Full Text Search capabilities using the pg_search gem.
You can also plug into frameworks like Solr or ElasticSearch to give you this functionality, but they will increase you development effort.
PG and MySQL both also have pattern matching functions that would allow you to search based on a regex string from the search values.

Rails Search Box

So I have a search box working in my application, however it only returns a result if the search matches exactly what is submitted, as opposed to something like it. Heres my code for the search method;
def self.search(search)
if search
where(:title => ["title LIKE ?", "#{search}"])
else
all
end
end
The "title LIKE ?" doesn't seem to be returning results which are like the query, only ones which are exactly the same.
What am I missing here?
Try this
where(["title LIKE ?", "%#{search}%"])
Here is another way if you want to avoid string queries (using arel):
where(arel_table[:title].matches("%#{search}%"))

Rails - wrong number of arguments (2 for 0..1) error

I am having trouble with some code inside an application I am working on.
With the following code:
#herbivores=Deer.find(:all,:conditions =>['state like?', '%' + params[:number]+'%'])
#herbi=#herbivores.find(:all,:conditions =>['city like?', '%bad%'])
I receive the error:
wrong number of arguments (2 for 0..1)
Can anybody explain what is happening?
Use the query API to keep the correct scope, and also do this more cleanly since where is chainable:
#herbivores=Deer.where('state like ?', '%' + params[:number]+'%')
#herbi=#herbivores.where('city like ?', '%bad%')
You can also chain these directly without an intermediate variable:
#herbi = Deer.where('state like ?', "%#{params[:number]}%").where('city like ?', "%bad%")
Or you can merge it into one method call:
#herbi = Deer.where('state like ? AND city like ?', "%#{params[:number]}%", "%bad%")
I believe what is happening is that you are treating #herbivores like its a model that you can find on, but it is an Array of Deer records so is not a model.
EDIT:
Purhaps you want:
#herbivores=Deer.find(:all,:conditions =>['state like ?', "%#{params[:number]}%"])
#herbivores.each do |herbi|
if herbi.city == 'bad'
puts "bad city in state #{ani.state}"
end
end

can you use activerecord to find substring of a field? (quick & dirty keyword finder)

Suppose a database contains a field 'keywords' and sample records include:
"pipe wrench"
"monkey wrench"
"crescent wrench"
"crescent roll"
"monkey bars"
is there a way in activerecord to find the records where the keyword field contains the substring "crescent"?
(It's just a quick and dirty lookup for a quick concept prototype)
Yeah, just use a LIKE statement in MySQL.
In Rails 2.x:
Table.find(:all, :conditions => ['keywords LIKE ?', '%crescent%'])
In Rails 3.x:
Table.where('keywords LIKE ?', '%crescent%').all
The Postgres database syntax would be:
YourModelName.where("yourFieldName like ?", "%" + yourSearchTerm + "%")
It all depends on your DB. Is it Postgres? MySQL? MongoDB? Anything else?
With Postgres, you could use something like :
Rails 2.x => Model.find(:all, :conditions=>["models.keywords ~= ?", 'crescent'])
Rails 3.x => Model.where("models.keywords ~= ?", 'crescent')
You just have to find the right syntax for your DB / Rails / ActiveRecord version.
I had a similar issue. I needed to see if there are keywords passed from conrolled input in the frontend component in the body of any questions in my questions table. Here is how I did it in my controller:
def search
input = params[:q]
#questions = Question.all
search_words = input.split(' ')
#found_question = [];
search_words.each do |word|
#found_question << Question.where("questions.body LIKE ?", "%#{word}%")
end
end

Rails - how to search based on a boolean field? (MySQL error)

I'm running the following query
#projects = #company.projects.where("active = ?", true).order("created_at ASC")
and I'm getting the error:
`ActiveRecord::StatementInvalid: Mysql::ParseError: You have an error in your SQL...`
the error points to the = '1'.
I've tried many variations on my query but I cannot figure out the problem. How can I solve this?
Try:
#projects = #company.projects.where(:active => true)
(it also works with strings 'active').
You can also look at
http://guides.rubyonrails.org/active_record_querying.html#hash-conditions
for more details.
There is also a nice railscast about this which explains why you might have problems (I'm not allowed to post 2 links so you should search for it :) )
You don't need to use parameterized queries with literals, just do this:
#projects = #company.projects.where("active = 1").order("created_at ASC")

Resources