I've seen several answers, but couldn't find anything that helps me
I have a Model which has a country column and a city column.
doing some SQL query, I want to add to that query a group by first country and for each country to group by city
Model.where("name LIKE ?", "%#{query}%").group(["country", "city"])
but I get
PG::GroupingError: ERROR: column "models.id" must appear in the GROUP BY clause or be used in an aggregate function
and I am not sure what to do, since I don't want to group by the ID, just by country and city
I am sure I am missing something here, not sure what
using the fields, as suggested with
Model.where("name LIKE ?", "%#{query}%").group("country, city").select("country, city")
still gives the same error
You should select before grouping
Model.where("name LIKE ?", "%#{query}%")
.select("country, city")
.group("country, city")
If you still have troubles with:
Model.where("name LIKE ?", "%#{query}%").group("country, city").select("country, city")
I guess you have defined a default scope, and you must do this way:
Model.unscoped.where("name LIKE ?", "%#{query}%").group("country, city").select("country, city")
Edited:
If it didn't works, you can do this and publish the output:
Model.where("name LIKE ?", "%#{query}%").group(["country", "city"]).to_sql
Related
Let's say, I have class Person with a field 'full_name'. How can I find all records where this field includes pattern 'smith'?
You can use Sql like or ilike queries
Edit as per #Vaibhav Kaushal comment
Person.where("full_name LIKE ?", "'%smith%'")
For MySQL database,
Person.where("full_name RLIKE ?", 'smith')
If you want to use OR i.e. find Person objects having full_name matching 'smith', 'roger' or 'dwane', you can use below,
Person.where("full_name RLIKE ?", 'smith | roger | dwane')
I am using User.where("name LIKE ?", "frodo") to find users with similar names.
It may return the following users
frodobaggins
frodo
frodo1
frodo2
....
How would I group all users by similar names (partially the same)?
Try this
User.find(:all, :conditions => ["name LIKE ?", "frodo%"])
or
User.where(["name LIKE ?", "frodo%"])
it return array of all user which name start with frodo.
From Divyang's answer, one small change to group users by name:--
User.where(["name LIKE ?", "frodo%"]).group(:name)
ActiveRecord provides a way to support group by clause. Checkout http://guides.rubyonrails.org/active_record_querying.html#group
I have some basic search implemented and I am trying to match multiple attribute to the 1 set of keywords.
I have this:
listings = Listing.order(:headline)
listings = listings.where("headline like ?", "%#{keywords}%") if keywords.present?
I have multiple attributes for listings that I would like to check to see if the keywords appear in - e.g. say listing.neighborhood.name or listing.type.name.
How do I write all of that in 1 statement? I tried:
listings = listings.where("headline like ? or neighborhood.name like ?", "%#{keywords}%")
But that returned this error:
ActiveRecord::PreparedStatementInvalid: wrong number of bind variables (1 for 2) in: headline like ? or neighborhood.name like ?
One obvious solution is just to add "%#{keywords}%" again...but that hardly seems DRY.
How do I add check both the neighborhood.name and type.name and others in that 1 query? Or should I be approaching this another way?
Thanks.
Edit 1:
When I try the non-DRY way of simply adding another {keywords} parameter, this is the error I get:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: neighborhood.name: SELECT "listings".* FROM "listings" WHERE (headline like '%sterling place%') AND (headline like '%sterling place%' or neighborhood.name like '%sterling place%') ORDER BY headline.
Which I think is because neighborhood is a foreign_key on my listings model, and not an attribute in and of itself. There is a simple association between the listings & neighborhood model.
Try this (still a non-DRY way) :
key = "%#{keywords}%"
listings = Listing.includes(:neighborhood).where("headline like ? or neighborhoods.name like ?", key, key)
I don't think you have many option to make it DRY... but you could do something like:
listings = listings.where("headline like :keywords or neighborhood.name like :keywords", :keywords => "%#{keywords}%")
Edit: I didn't realise the association... siekfried is right... just a little more DRY if you start adding more columns:
listings = Listing.includes(:neighborhood).where("listings.headline like :keywords or neighborhoods.name like :keywords", :keywords => "%#{keywords}%")
Try:
listings = listings.where("headline like ? or neighborhood.name like ?", "%#{keywords}%", "%#{keywords}%")
Here is an activerecord query i'm trying to use in rails
q = "Manchester"
b = "John Smith"
Model.find(:all, :conditions => ["city ? AND name like ?", q, b])
but i get this error in rails console
ActiveRecord::StatementInvalid: SQLite3::SQLException: near "'Manchester'": syntax error: SELECT "model".* FROM "model" WHERE (city 'Manchester' AND name like 'John Smith')
Please help!
You missed LIKE for city.
Model.where('city LIKE ? AND name LIKE ?', "%#{q}%", "%#{b}%");
You can also use this syntax which is a lot more readable than trying to figure out which ? goes with which variable. I mean if you have 1 or 2 it's fine, but once you have more it gets pretty ugly.
Model.where("city LIKE :city AND name LIKE :name", { city: "%#{q}%", name: "%#{b}%" })
The placeholders and hash key can be anything you like as long as they match (don't use :city and then hamster: in the hash key for example).
The nice thing about this is that you can also use one variable for multiple searches:
where("user LIKE :term OR email LIKE :term OR friends LIKE :term", { term: "%#{params[:term]}%"})
Try this:
Model.find(:all, :conditions => ["city = ? AND name like ?", q, b])
I am currently using scopes in my model to perform searches within a database. I can stack these scopes and it will output results matching all parameters.
scope :search_between, lambda{|begin_date, end_date|
where "sub.date BETWEEN ? AND ?", begin_date, end_date
}
What I am having trouble with is integrating a keywords search that will search the entire database and output the results that contain the sum of the keywords. I would like to do something like this (displayed for simplicity):
scope :keywords, lambda{|search|
search.chomp.split(/,\s*/) do |item|
where "date like ? or city like ? or state like ?", "%#{item}%" and
where "date like ? or city like ? or state like ?", "%#{item}%" and
where "date like ? or city like ? or state like ?", "%#{item}%"
end
}
I am currently using something like this to take care of searching multiple columns:
scope :keywords, lambda{|search|
search.chomp.split(/,\s*/) do |item|
where(Sub.column_names.map {|cn| "#{cn} like ?" }.join("or "), "%#{item}%"] Sub.column_names.size)).join(' AND ')
end
}
My problem is that I want to do multiple "where()'s" in the scope. Is it possible and if so, how?
Just turn it into a method that returns a scope:def self.keywords(search)
scope = self.scoped
search.chomp.split(/,\s*/).each do |item|
scope = scope.where(["date like ? or
city like ? or
state like ?", "%#{item}%","%#{item}%","%#{item}%"])
end
scope
end
The drawback is that you can't chain keywords off of other scopes, but you can chain other scopes off of keywords.
I think you will be hitting the limit with using the database for full text search.
Have you looked into using Solr or Sphinx for your full text searches? There's also IndexTank if you want to use a 3rd party service.
For solr, there are rubygems available to help you: sunspot, solrsan(i'm the author)
Sunspot is definitely more full-featured and solrsan is a barebones layer.