Rails基于params的自定义查询

时间:2014-05-04 02:50:45

标签: mysql sql ruby-on-rails activerecord rails-activerecord

我从json请求发送了零或多个过滤器参数。 参数可能包含:

params[:category_ids"]
params[:npo_ids"]

我正在尝试使用选定的ID从我的数据库中检索所有项目。这是我目前的情况:

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 ...

这真的不起作用,但希望它能让你知道我想做什么。

如何根据我不确定的params来过滤我的activerecord查询。

也许我可以做多个查询然后加入它们......或者我应该在模型中放一个filter_by_params方法......?

您认为这样做的好方法是什么?

2 个答案:

答案 0 :(得分:2)

在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

您使用的语法看起来像rails 2样式;希望你使用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    

答案 1 :(得分:2)

我解决了这个问题。这是我的代码

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

基本上它将.where条件存储在@conditions中,当有类别和npos时,它看起来像这样:

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

然后将其插入

Project.joins(:categories).where(@conditions)

似乎有效。

如果您要过滤has_many关系,则必须加入。加入后,请确保通过执行以下操作来调用您所指的特定表:

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