I've encountered a performance issue where Processing.all
gets called prior to a filter, which in turn runs a second query on the Processing
model. Processing
has a good number of records, and loading them all into memory, only to run a second query on them is causing a spike in RAM which I'd like to fix.
The line in the controller is:
@filter = ProcessingFilter.new(base_collection: Processing.all, options: params[:filter])
As you can see, Processing.all
is being passed in here as the base_collection
param.
The ProcessingFilter
then runs:
class ProcessingFilter
def initialize(base_collection:, options: {})
@base_collection = base_collection
@options = options
end
def collection
@collection ||= begin
scope = @base_collection
if condition1
scope = scope.joins(:another_entry).where(another_entry: {customer_id: customer_id})
end
if condition2
scope = scope.where('created_at >= ?', created_at_start)
end
if condition3
scope = scope.where('created_at <= ?', created_at_end)
end
if condition4
scope = scope.where(number: processing_number)
end
scope
end
end
end
This filter chains together the various if conditions creating a single ActiveRecord query, which is fine.
The problem is that I cannot do away with this filter as it sets some instance variables that are being used elsewhere. I'm trying to think of a clever way to not have the Processing.all
query run the first time, but instead have it chain together the other options despite being in a separate class. Is this possible?
Thanks in advance!