I finally got my filterrific get working and its a great gem, if not a little complex for a noob like me.
My original index page was filtering the active records based on those nearby to the user like this:
def index
location_ids = Location.near([session[:latitude], session[:longitude]], 50, order: '').pluck(:id)
@vendor_locations = VendorLocation.includes(:location).where(location_id: location_ids)
@appointments = Appointment.includes(:vendor).
where(vendor_id: @vendor_locations.select(:vendor_id))
end
So this pulls in all of the Appointments with Vendors in the area, but how do I pass this over to the Filterrific search:
@filterrific = initialize_filterrific(
params[:filterrific],
select_options:{ sorted_by: Appointment.options_for_sorted_by, with_service_id: Service.options_for_select },
) or return
@appointments = @filterrific.find.page(params[:page])
respond_to do |format|
format.html
format.js
end
It seems like the Filterrerrific is loading ALL of the appointments by default, but I want to limit to the ones nearby. What am I missing?
What you appear to be missing is a param
default_filter_params
to filterrific macro in the model. (Your question didn't mention that you made any adjustments to the VendorLocation model, since that is the object that you want to filter, that's where the macro should be called. Maybe you just omitted it from your question...)From the model docs:
You probably found this already, it was on the first page of the documentation, but there's more important stuff in the example application that you need (I ran into this too, when I was just recently using Filterrific for the first time.)
The information on the start page is not enough to really get you started at all. You have to read a bit further to see the other ways you may need to change your models, model accesses, and views in order to support Filterrific.
The part that makes the default filter setting effective is this
default_filter_params
hash (NOTselect_options
, which provides the options for "select" aka dropdown boxes. That's not what you want at all, unless you're doing a dropdown filter.) This hash holds a list of the scopes that need to be applied by default (the hash keys) and the scope parameter is used as the hash value.That
default_filter_params
hash may not be the only thing you are missing... You also must define those ActiveRecord scopes for each filter that you want to use in the model, and name these inavailable_filters
as above to make them available to filterrific:It's important that these scopes all take an argument (the value comes from the value of the filter field on the view page, you must add these to your view even if you want to keep them hidden from the user). It's also important that they always return ActiveRecord associations.
This is more like what you want:
The problem with this approach is that in your case, there is no location_string or any single location variable, you have multiple coordinates for your location parameters. But you are not the first person to have this problem at all!
This issue describes almost exactly the problem you set out to solve. The author of Filterrific recommended embedding the location fields into hidden form fields in a nested
fields_for
, so that the form can still pass a single argument into the scope (as inwith_distance_fields
):... make that change in your view, and add a matching scope that looks something like (copied from the linked GitHub issue):
So, your
:with_distance
scope should go onto theVendorLocation
model and it should probably look like this:Last but not least, you probably noticed that I removed your call to
includes(:location)
— I know you put it there on purpose, and I didn't find it very clear in the documentation, but you can still get eager loading and have ActiveRecord optimize into a single query before passing off the filter work to Filterrific by defining your controller's index method in this way:Hope this helps!