Rails filter when param is present for large model

末鹿安然 提交于 2020-01-24 01:01:06

问题


This blog post explains how to filter based on the parameters that are present with this code.

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

The Product.where(nil) part of the solution is problematic because it will load everything into memory and cause your server to crash if the model is big.

One of the blog post commenters said "Isn't it better to use Product.none instead of Product.where(nil)?" but I couldn't get that solution to work.

This Stackoverflow answer accesses the ActiveRecord::Relation object via the joins method. I'm not doing a join, so this solution won't work for me.

Let me know if there is a better way to do this or a completely different way I should approach this problem. Thanks!


回答1:


Can you do something like:

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



回答2:


Why not just use .all and merge in additional scopes?

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


来源:https://stackoverflow.com/questions/49017124/rails-filter-when-param-is-present-for-large-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!