简体   繁体   English

基于参数的Rails自定义查询

[英]Rails custom query based on params

I have zero or many filter params being sent from a json request. 我从JSON请求发送了零个或多个过滤器参数。 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. 我正在尝试使用选定的ID从数据库中检索所有项目。 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. 如何根据不确定的参数筛选ActiveRecord查询。

Maybe I can do multiple queries and then join them... Or maybe I should put a filter_by_params method in the Model...? 也许我可以先执行多个查询,然后再将它们加入...或者应该在模型中放置一个filter_by_params方法...?

What do you think is a good way to do this? 您认为这样做的好方法是什么?

In rails 3 and above you build queries using ActiveRelation objects, no sql is executed until you try to access the results, ie 在Rails 3和更高版本中,您使用ActiveRelation对象构建查询,直到尝试访问结果,SQL才会执行,即

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; 您使用的语法看起来像rails 2样式; hopefully you are using 3 or above and if so you should be able to do something like 希望您使用的是3或更高,如果可以,您应该可以执行类似的操作

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    

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: 基本上,它将.where条件存储在@conditions中,当同时存在类别和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. 如果要过滤has_many关系,则必须加入。 Then after joining, make sure to call the specific table you're referring to by doing something like this: 然后,在加入后,请确保通过执行以下操作来调用您要引用的特定表:

:categories => {:id => [1,2,3]}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM