问题
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