Module: IntrospectiveGrape::Filters
- Included in:
- API
- Defined in:
- lib/introspective_grape/filters.rb
Instance Method Summary collapse
- #apply_filter_params(klass, model, api_params, params, records) ⇒ Object
- #apply_filters(records, filters) ⇒ Object
- #apply_simple_filter(klass, model, params, records, field) ⇒ Object
- #custom_filter(*args) ⇒ Object
- #custom_filters(*args) ⇒ Object
- #declare_filter_params(dsl, klass, model, api_params) ⇒ Object
- #declare_simple_filter(dsl, klass, model, field) ⇒ Object
-
#default_sort(*args) ⇒ Object
Allow filters on all whitelisted model attributes (from api_params) and declare customer filters for the index in a method.
- #filter_doc ⇒ Object
- #filter_on(*args) ⇒ Object
- #filters(*args) ⇒ Object
- #humanize_date_range(field) ⇒ Object
- #identifier_filter?(model, field) ⇒ Boolean
- #simple_filters(klass, model, api_params) ⇒ Object
- #special_filter_enabled?(filters) ⇒ Boolean
- #timestamp_filter(klass, model, field) ⇒ Object
Instance Method Details
#apply_filter_params(klass, model, api_params, params, records) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/introspective_grape/filters.rb', line 102 def apply_filter_params(klass, model, api_params, params, records) records = records.order(default_sort) if default_sort.present? simple_filters(klass, model, api_params).each do |field| records = apply_simple_filter(klass, model, params, records, field) end klass.custom_filters.each do |filter, _details| records = records.send(filter, params[filter]) end records = apply_filters(records, params[:filter]) records.where( JSON.parse(params[:query]) ) if params[:query].present? records end |
#apply_filters(records, filters) ⇒ Object
118 119 120 121 122 123 124 125 126 |
# File 'lib/introspective_grape/filters.rb', line 118 def apply_filters(records, filters) if filters.present? filters = JSON.parse( filters.delete('\\') ) filters.each do |key, value| records = records.where(key => value) if value.present? end end records end |
#apply_simple_filter(klass, model, params, records, field) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/introspective_grape/filters.rb', line 89 def apply_simple_filter(klass, model, params, records, field) return records if params[field].blank? if (klass, model, field) op = field.ends_with?('_start') ? '>=' : '<=' records.where(ActiveRecord::Base.sanitize_sql_array(["#{(klass, model, field)} #{op} ?", Time.zone.parse(params[field])])) elsif model.respond_to?("#{field}=") records.send("#{field}=", params[field]) else records.where(field => params[field]) end end |
#custom_filter(*args) ⇒ Object
10 11 12 |
# File 'lib/introspective_grape/filters.rb', line 10 def custom_filter(*args) custom_filters( *args ) end |
#custom_filters(*args) ⇒ Object
14 15 16 17 18 |
# File 'lib/introspective_grape/filters.rb', line 14 def custom_filters(*args) @custom_filters ||= {} @custom_filters = Hash[*args].merge(@custom_filters) if args.present? @custom_filters end |
#declare_filter_params(dsl, klass, model, api_params) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/introspective_grape/filters.rb', line 47 def declare_filter_params(dsl, klass, model, api_params) # Declare optional parameters for filtering parameters, create two parameters per # timestamp, a Start and an End, to apply a date range. simple_filters(klass, model, api_params).each do |field| declare_simple_filter(dsl, klass, model, field) end custom_filters.each do |filter, details| dsl.optional filter, details end dsl.optional :filter, type: String, description: filter_doc if special_filter_enabled?(filters) end |
#declare_simple_filter(dsl, klass, model, field) ⇒ Object
61 62 63 64 65 66 67 68 69 |
# File 'lib/introspective_grape/filters.rb', line 61 def declare_simple_filter(dsl, klass, model, field) if (klass, model, field) dsl.optional field, type: klass.param_type(model, field), description: "Constrain #{field} by #{humanize_date_range(field)} date." elsif identifier_filter?(model, field) dsl.optional field, type: Array[String], coerce_with: ->(val) { val.split(',') }, description: 'Filter by a comma separated list of unique identifiers.' else dsl.optional field, type: klass.param_type(model, field), description: "Filter on #{field} by value." end end |
#default_sort(*args) ⇒ Object
Allow filters on all whitelisted model attributes (from api_params) and declare customer filters for the index in a method.
6 7 8 |
# File 'lib/introspective_grape/filters.rb', line 6 def default_sort(*args) @default_sort ||= args end |
#filter_doc ⇒ Object
83 84 85 86 87 |
# File 'lib/introspective_grape/filters.rb', line 83 def filter_doc <<-STR JSON of conditions for query. If you're familiar with ActiveRecord's query conventions you can build more complex filters, i.e. against included child associations, e.g.: {\"<association_name>_<parent>\":{\"field\":\"value\"}} STR end |
#filter_on(*args) ⇒ Object
20 21 22 |
# File 'lib/introspective_grape/filters.rb', line 20 def filter_on(*args) filters( *args ) end |
#filters(*args) ⇒ Object
24 25 26 27 28 |
# File 'lib/introspective_grape/filters.rb', line 24 def filters(*args) @filters ||= [] @filters += args if args.present? @filters end |
#humanize_date_range(field) ⇒ Object
71 72 73 |
# File 'lib/introspective_grape/filters.rb', line 71 def humanize_date_range(field) field.ends_with?('_start') ? 'initial' : 'terminal' end |
#identifier_filter?(model, field) ⇒ Boolean
75 76 77 |
# File 'lib/introspective_grape/filters.rb', line 75 def identifier_filter?(model, field) true if field.ends_with?('id') && %i(integer uuid).include?(model.columns_hash[field]&.type) end |
#simple_filters(klass, model, api_params) ⇒ Object
30 31 32 33 34 35 36 |
# File 'lib/introspective_grape/filters.rb', line 30 def simple_filters(klass, model, api_params) @simple_filters ||= api_params.select {|p| p.is_a? Symbol }.select {|field| filters.include?(:all) || filters.include?(field) }.map {|field| (klass.param_type(model, field) == DateTime ? ["#{field}_start", "#{field}_end"] : field.to_s) }.flatten end |
#special_filter_enabled?(filters) ⇒ Boolean
79 80 81 |
# File 'lib/introspective_grape/filters.rb', line 79 def special_filter_enabled?(filters) filters.include?(:all) || filters.include?(:filter) end |
#timestamp_filter(klass, model, field) ⇒ Object
38 39 40 41 42 43 44 45 |
# File 'lib/introspective_grape/filters.rb', line 38 def (klass, model, field) filter = field.sub(/_(end|start)\z/, '') if field =~ /_(end|start)\z/ && klass.param_type(model, filter) == DateTime filter else false end end |