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

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")

Related

Ruby on Rails search method

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

How do I do an "or" based search in sunspot?

I have several categories of facets I'm looking for and in one I want, when the user clicks more than one filter in that particular category, to have the results sunspot returns include everything that matches either of the choices, not only both. I tried this:
#search = ProfileSearch.new(search_params) do
facet_restriction = with(:grad_year,params[:grad_year])
facet(:grad_year, :exclude => facet_restriction)
end
But that doesn't seem to be working at all? Am I not using multiselect facets in the appropriate way or should I be looking at doing something entirely different?
Any thoughts would be appreciated.
I think it should be
#search = ProfileSearch.search(search_params) do
facet_restriction = with(:grad_year,params[:grad_year])
facet(:grad_year, :exclude => facet_restriction)
end
I do something like this:
grad_year_exclusions = []
if params[:grad_year].present?
grad_year_exclusions << with(:grad_year).any_of(params[:grad_year])
end
grad_year_exclusions.compact!
grad_year_exclusions = nil if grad_year_exclusions.empty?
facet(:grad_year, exclude: grad_year_exclusions)
(params[:grad_year] being an array)
Hope this helps.

Find Record based on the associated attributes

I am trying to find a record based on two associated attributes. The Record should be selected, if its association contains those two records.
So far, I tried following - Which seemed to me a very bad practice and I want to avoid using it.
#size = Spree::OptionValue.find(params[:size])
#color = Spree::OptionValue.find(params[:color])
vari = Spree::Variant.all
vari.each do |va|
if va.option_values.include?(#size && #color)
#variant = va
end
end
So far, I also tried
#variant = Spree::Variant.all(:include => :option_values, :conditions => ['option_value.id = ?', params[:color])
This seems to be the way to go, but I can't seem to figure out the right way to get the result.
The return error I keep on getting is following:
ActiveRecord::StatementInvalid: PG::Error: ERROR: missing FROM-clause entry for table "option_values"
LINE 1: ..._option_values_variants"."option_value_id" WHERE (option_val...
EDIT:
I got it working due to the great help given in the accepted answer:
Spree::Variant.joins(:option_values).where("spree_option_values.id in (?)", [size, color])
First off, your code is probably broken. I doubt that .include?(#size && #color) does what you think it does; you're effectively only checking if option_values includes #color. This is equivalent to doing (true && #color). If you want to include both values, you need .include?(#size) && .include?(#color).
So your code should probably look like this:
vari = Spree::Variant.all
vari.each do |va|
if va.option_values.include?(#size) && va.option_values.include?(#color)
#variant = va
end
end
Next, you can make your code much more Ruby-esque:
#variant = Spree::Variant.all.select do |v|
v.option_values.include?(#size) && v.option_values.include?(#color)
end
But it's far better to actually evaluate the condition at the database level rather than load the entire table into your application. You seem to be looking for all records where the associated OptionValues includes the two you've selected into #size and #color.
The query you're looking for probably looks something like this:
Spree::Variant.joins(:option_values).where("option_values.id in (?)", [#size, #color])

Rails 3.1: 'where' with multiple conditions and 'not nil' verification

I want to find records with multiple conditions and this is my code:
#calhappybd = Client.where(:user_id => current_user.id, "birth IS NOT NULL")
I'm trying to do this with squeel-gem, but when I try to use multiple conditions (where{(cond1)(cond2)}), but my current_user.id defined as simple string-data.
With squeel, you should be able to do something like
#calhappybd = Client.where{(user_id == current_user.id) & (birth != nil)}
Let know if you get the same error again...
UPDATED:
Modified the conditions above. Note the single ampersand and double equals. That works for me..
My configuration:
rails 3.1.0.rc6
squeel 0.8.8

Rails - Conditional Query, with ActiveRecord?

Given a query like:
current_user.conversations.where("params[:projectid] = ?", projectid).limit(10).find(:all)
params[:projectid] is being sent from jQuery ajax. Sometimes that is an integer and the above works fine. But if the use selects "All Projects, that's a value of '' which rails turns into 0. which yields an invalid query
How with rails do you say search params[:projectid] = ? if defined?
Thanks
I think you may have mistyped the query a bit. "params[:projectid] = ?" shouldn't be a valid query condition under any circumstances.
In any case, you could do some sort of conditional statement:
if params[:project_id].blank?
#conversations = current_user.conversations.limit(10)
else
#conversations = current_user.conversations.where("project_id = ?", params[:project_id]).limit(10)
end
Although, I'd probably prefer something like this:
#conversations = current_user.conversations.limit(10)
#converstaions.where("project_id = ?", params[:project_id]) unless params[:project_id].blank?
Sidenotes:
You don't have to use .find(:all). Rails will automatically execute the query when the resultset is required (such as when you do #conversations.each).
Wherever possible, try to adhere to Rails' snakecasing naming scheme (eg. project_id as opposed to projectid). You'll save yourself and collaborators a lot of headaches in the long run.
Thanks but if the where query has lets say 3 params, project_id, project_status, ... for example, then the unless idea won't work. I'm shocked that Rails doesn't have a better way to handle conditional query params
EDIT: If you have multiple params that could be a part of the query, consider the fact that where takes a hash as its argument. With that, you can easily build a parameter hash dynamically, and pass it to where. Something like this, maybe:
conditions = [:project_id, :project_status, :something_else].inject({}) do |hsh, field|
hsh[field] = params[field] unless params[field].blank?
hsh
end
#conversations = current_user.conversations.where(conditions).limit(10)
In the above case, you'd loop over all fields in the array, and add each one of them to the resulting hash unless it's blank. Then, you pass the hash to the where function, and everything's fine and dandy.
I didn't understand why you put:
where("params[:projectid] = ?", projectid)
if you receive params[:project] from the ajax request, the query string shouldn't be:
where("projectid = ?", params[:projectid])
intead?
And if you are receiving an empty string ('') as the parameter you can always test for:
unless params[:projectid].blank?
I don't think i undestood your question, but i hope this helps.

Resources