当大型模型存在param时Rails过滤
此博客文章介绍了如何根据此代码中的参数进行过滤。
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)
是不是更好?” 但我无法让这个解决方案奏效。
此Stackoverflow应答通过joins
方法访问ActiveRecord::Relation
对象。 我没有加入,所以这个解决方案对我不起作用。
让我知道如果有更好的方法来完成这个或完全不同的方式我应该解决这个问题。 谢谢!
你可以这样做:
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
为什么不直接使用.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