Module: IntrospectiveGrape::Filters

Included in:
API
Defined in:
lib/introspective_grape/filters.rb

Instance Method Summary collapse

Instance Method Details

#apply_filter_params(klass, model, api_params, params, records) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/introspective_grape/filters.rb', line 91

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

  if params[:filter].present?
    filters = JSON.parse( params[:filter].delete('\\') )
    filters.each do |key, value|
      records = records.where(key => value) if value.present?
    end
  end

  records.where( JSON.parse(params[:query]) ) if params[:query].present?

  records
end

#apply_simple_filter(klass, model, params, records, field) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/introspective_grape/filters.rb', line 78

def apply_simple_filter(klass, model, params, records, field)
  return records if params[field].blank?

  if timestamp_filter(klass,model,field)
    op      = field.ends_with?("_start") ? ">=" : "<="
    records.where("#{timestamp_filter(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



11
12
13
# File 'lib/introspective_grape/filters.rb', line 11

def custom_filter(*args)
  custom_filters( *args )
end

#custom_filters(*args) ⇒ Object



15
16
17
18
19
# File 'lib/introspective_grape/filters.rb', line 15

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



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/introspective_grape/filters.rb', line 56

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|
    if timestamp_filter(klass,model,field)
      terminal = field.ends_with?("_start") ? "initial" : "terminal"
      dsl.optional field, type: klass.param_type(model,field), description: "Constrain #{field} by #{terminal} date."
    elsif identifier_filter(klass,model,field)
      dsl.optional field, type: Array[Integer], coerce_with: ->(val) { val.split(',') }, description: "Filter by a comma separated list of integers."
    else
      dsl.optional field, type: klass.param_type(model,field), description: "Filter on #{field} by value."
    end
  end

  custom_filters.each do |filter,details|
    dsl.optional filter, details
  end

  dsl.optional :filter, type: String, description: "JSON of conditions for query. If you're familiar with ActiveRecord's query conventions you can build more complex filters, e.g. against included child associations, e.g. {\"&lt;association_name&gt;_&lt;parent&gt;\":{\"field\":\"value\"}}" if filters.include?(:all) || filters.include?(:filter)
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.



7
8
9
# File 'lib/introspective_grape/filters.rb', line 7

def default_sort(*args)
  @default_sort ||= args
end

#filter_on(*args) ⇒ Object



21
22
23
# File 'lib/introspective_grape/filters.rb', line 21

def filter_on(*args)
  filters( *args )
end

#filters(*args) ⇒ Object



25
26
27
28
29
# File 'lib/introspective_grape/filters.rb', line 25

def filters(*args)
  @filters ||= []
  @filters   = @filters+args if args.present?
  @filters
end

#identifier_filter(klass, model, field) ⇒ Object



48
49
50
51
52
53
54
# File 'lib/introspective_grape/filters.rb', line 48

def identifier_filter(klass,model,field)
  if field.ends_with?('id') && klass.param_type(model,field) == Integer
    field
  else
    false
  end
end

#simple_filters(klass, model, api_params) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/introspective_grape/filters.rb', line 31

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

#timestamp_filter(klass, model, field) ⇒ Object



39
40
41
42
43
44
45
46
# File 'lib/introspective_grape/filters.rb', line 39

def timestamp_filter(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