Mongoid动态查询

xax*_*axa 2 mongoid ruby-on-rails-3

这一定是一个简单的,但我被卡住了...所以我使用Rails#3和Mongoid,并希望动态构建依赖于传递参数的查询,然后执行find().就像是

def select_posts
    query = :all # pseudo-code here
    if (params.has_key?(:author))
        query += where(:author => params[:author]) # this is pseudo-code again
    end

    if (params.has_key?(:post_date))
        query += where(:create_date => params[:post_date]) # stay with me
    end

    @post_bodies = []
    Post.find(query).each do |post| # last one
        @post_bodies << post.body
    end

    respond_to do |format|
        format.html
        format.json { render :json => @post_bodies }
    end
end
Run Code Online (Sandbox Code Playgroud)

the*_*RON 5

您可以在此处使用几种不同的选项 - 具体取决于您的实际应用程序的复杂程度.直接使用您的示例 - 您最终可能会遇到以下情况:

query = Post.all
query = query.where(:author => params[:author]) if params.has_key?(:author)
query = query.where(:create_date => params[:post_date]) if params.has_key?(:post_date)
@post_bodies = query.map{|post| post.body}
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为Mongoid中的查询(Criteria)是可链接的.


或者,如果您希望使用更多字段,则可以执行以下操作:

query = Post.all
fields = {:author => :author, :post_date => :create_date}
fields.each do |params_field, model_field|
  query = query.where(model_field => params[params_field]) if params.has_key?(params_field)
end
@post_bodies = query.map{|post| post.body}
Run Code Online (Sandbox Code Playgroud)

最后,您可以进一步使用它并正确嵌套表单参数,并命名参数以使它们与您的模型匹配,以便您的params对象看起来像这样:

params[:post] = {:author => "John Smith", :create_date => "1/1/1970", :another_field => "Lorem ipsum"}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

@post_bodies = Post.where(params[:post]).map{|post| post.body}
Run Code Online (Sandbox Code Playgroud)

当然,在最后一个示例中,您需要清理输入字段 - 以防止恶意用户篡改行为.