Skip to content

Instantly share code, notes, and snippets.

@justinweiss
Last active January 11, 2024 07:28
Show Gist options
  • Save justinweiss/9065666 to your computer and use it in GitHub Desktop.
Save justinweiss/9065666 to your computer and use it in GitHub Desktop.
Filterable
# Call scopes directly from your URL params:
#
# @products = Product.filter(params.slice(:status, :location, :starts_with))
module Filterable
extend ActiveSupport::Concern
module ClassMethods
# Call the class methods with names based on the keys in <tt>filtering_params</tt>
# with their associated values. For example, "{ status: 'delayed' }" would call
# `filter_by_status('delayed')`. Most useful for calling named scopes from
# URL params. Make sure you don't pass stuff directly from the web without
# whitelisting only the params you care about first!
def filter(filtering_params)
results = self.where(nil) # create an anonymous scope
filtering_params.each do |key, value|
results = results.public_send("filter_by_#{key}", value) if value.present?
end
results
end
end
end
@khalilgharbaoui
Copy link

khalilgharbaoui commented May 22, 2019

My very own version:
without the explicit anonymous scope and redundant self's

module Filterable
  extend ActiveSupport::Concern
  class_methods do
    def filter(filter_attributes, params)
      results = all;
      filter_attributes.each do |attribute|
        results = results.send(attribute, params[attribute]) if params[attribute].present?
      end
      results
    end
  end
end

@RameshGhk
Copy link

Hi All,
I would like to know how can I implement this Filterable module in my views. I ma new to Rails..
I have table with 40 plus columns but I would like to apply filters for few columns like :status, :name etc
I should be able to dropdown, select the required status and apply filters

thanks inadvance for your support..

@heratyian
Copy link

I had some issues using this with pundit gem policy scopes. I suggest renaming filter to filter_by. Has the benefit of consistent naming with scopes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment