Reputation: 705
I have zero or many filter params being sent from a json request. the params may contain:
params[:category_ids"]
params[:npo_ids"]
etc.
I am trying to retreive all Projects from my database with the selected ids. Here is what I have currently:
def index
if params[:category_ids].present? || params[:npo_ids].present?
@conditions = []
@ids = []
if params["category_ids"].present?
@conditions << '"category_id => ?"'
@ids << params["category_ids"].collect{|x| x.to_i}
end
if params["npo_ids"].present?
@conditions << '"npo_id => ?"'
@ids << params["npo_ids"].collect{|x| x.to_i}
end
@conditions = @ids.unshift(@conditions.join(" AND "))
@projects = Project.find(:all, :conditions => @conditions)
else ...
This really isn't working, but hopefully it gives you an idea of what I'm trying to do.
How do I filter down my activerecord query based on params that I'm unsure will be there.
Maybe I can do multiple queries and then join them... Or maybe I should put a filter_by_params method in the Model...?
What do you think is a good way to do this?
Upvotes: 0
Views: 845
Reputation: 705
I solved this. here's my code
def index
if params[:category_ids].present? || params[:npo_ids].present?
@conditions = {}
if params["category_ids"].present?
@conditions["categories"] = {:id => params["category_ids"].collect{|x| x.to_i}}
end
if params["npo_ids"].present?
@conditions["npo_id"] = params["npo_ids"].collect{|x| x.to_i}
end
@projects = Project.joins(:categories).where(@conditions)
else
basically it stored the .where conditions in @conditions, which looks something like this when there's both categories and npos:
{:categories => {:id => [1,2,3]}, :npo_id => [1,2,3]}
Then inserting this into
Project.joins(:categories).where(@conditions)
seems to work.
If you're filtering on a has_many relationship, you have to join. Then after joining, make sure to call the specific table you're referring to by doing something like this:
:categories => {:id => [1,2,3]}
Upvotes: 2
Reputation: 20614
In rails 3 and above you build queries using ActiveRelation objects, no sql is executed until you try to access the results, i.e.
query = Project.where(is_active: true)
# no sql has been executed
query.each { |project| puts project.id }
# sql executed when the first item is accessed
The syntax you are using looks like rails 2 style; hopefully you are using 3 or above and if so you should be able to do something like
query = Project.order(:name)
query = query.where("category_id IN (?)", params[:category_ids]) if params[:category_ids].present?
query = query.where("npo_ids IN (?)", params[:npo_ids]) if params[:npo_ids].present?
@projects = query
Upvotes: 2