当大型模型存在param时,Rails会过滤

问题描述 投票:0回答:2

This blog post解释了如何根据此代码中的参数进行过滤。

def index
  @products = Product.where(nil) # creates an anonymous scope
  @products = @products.status(params[:status]) if params[:status].present?
  @products = @products.location(params[:location]) if params[:location].present?
  @products = @products.starts_with(params[:starts_with]) if params[:starts_with].present?
end

Product.where(nil)解决方案的一部分是有问题的,因为它会将所有内容加载到内存中,如果模型很大,会导致服务器崩溃。

其中一篇博文评论者说:“用Product.none代替Product.where(nil)不是更好吗?”但我无法让这个解决方案奏效。

This Stackoverflow answer通过ActiveRecord::Relation方法访问joins对象。我没有加入,所以这个解决方案对我不起作用。

让我知道,如果有更好的方法来做到这一点或完全不同的方式我应该解决这个问题。谢谢!

ruby-on-rails activerecord
2个回答
1
投票

你可以这样做:

def index
  [:status, :location, :starts_with].each do |param_sym|
    @products = (@products ? @products : Product).send(param_sym, params[param_sym]) if params[param_sym].present?
  end
end

1
投票

为什么不使用.all并合并其他范围?

def filter_by_params
  params.slice(:status, :location, :starts_with)
    .compact # removes keys with nil values
    # iterates though the hash and returns a scope
    .each_with_object(Product.all) do |(key, value), scope|
      scope.merge(Product.send(key, value))
    end
end
© www.soinside.com 2019 - 2024. All rights reserved.