rest_framework 0.8.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a54e0539466e7981ab8ba95a1877ad705b46279309c1d3bfd2cfd038e916b2b
4
- data.tar.gz: c26e553c6b4b5435545ffb5fa71c59720f42303347b35336077c764b00fd889d
3
+ metadata.gz: 333e3109a118ca9b6069e4856d77ec85baf217b8f0e835f6f1426c93674822bd
4
+ data.tar.gz: e187f2d6f01b5eb69d358fb0f5da134120c4a04c76eb06e8c181deb16a6d317a
5
5
  SHA512:
6
- metadata.gz: 79a80f7d7b3ab044203b612fc8ed453c3a7490a17e9e53adb8386719b9d6944838e78ce343d3596ac8c370cc6dc122d2ede66ec2afce7ffaa9dc635ed23146ad
7
- data.tar.gz: 2943c3779a404ff67f64f6c38001c9de828f3f536c79da1663b02dad0f4c6b20fa36fcd0e4310cbffda48dc4db6c329d09c5e7c48d93e62dc53a157b86e75eef
6
+ metadata.gz: 875514cb611fe74eaddeda88c2e48dcb7e28246274b8e191c7e13410998ce462c0a6dff1cbdc0cc9140a3e6e56026aecbcfbc4c002d230e36f7c315bebd5c84a
7
+ data.tar.gz: b82c26a854b08314c4e56d2a29532570289fad186d2f0019421f6214f1ad35fa60e4730a5b2d8c06b0bd776f28c291cb1d33740131f2f030912c527eca3dcc87
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.3
1
+ 0.8.4
@@ -439,10 +439,13 @@ module RESTFramework::BaseModelControllerMixin
439
439
  return super || RESTFramework::NativeSerializer
440
440
  end
441
441
 
442
- # Get filtering backends, defaulting to using `ModelFilter` and `ModelOrderingFilter`.
442
+ # Get filtering backends, defaulting to using `ModelFilter`, `ModelOrderingFilter`, and
443
+ # `ModelSearchFilter`.
443
444
  def get_filter_backends
444
445
  return self.class.filter_backends || [
445
- RESTFramework::ModelFilter, RESTFramework::ModelOrderingFilter
446
+ RESTFramework::ModelFilter,
447
+ RESTFramework::ModelOrderingFilter,
448
+ RESTFramework::ModelSearchFilter,
446
449
  ]
447
450
  end
448
451
 
@@ -117,25 +117,35 @@ end
117
117
 
118
118
  # Multi-field text searching on models.
119
119
  class RESTFramework::ModelSearchFilter < RESTFramework::BaseFilter
120
- # Get a list of search fields for the current action. Fallback to columns because we need an
121
- # explicit list of columns to search on, so `nil` is useless in this context.
120
+ DEFAULT_SEARCH_COLUMNS = %w[name email title description note]
121
+
122
+ # Get a list of search fields for the current action. Fallback to columns but only grab a few
123
+ # common string-like columns by default.
122
124
  def _get_fields
123
- return @controller.class.search_fields || @controller.get_fields(fallback: true)
125
+ if search_fields = @controller.class.search_fields
126
+ return search_fields
127
+ end
128
+
129
+ columns = @controller.class.get_model.columns_hash.keys
130
+ return @controller.get_fields(fallback: true).select { |f|
131
+ f.in?(DEFAULT_SEARCH_COLUMNS) && f.in?(columns)
132
+ }
124
133
  end
125
134
 
126
135
  # Filter data according to the request query parameters.
127
136
  def get_filtered_data(data)
128
- fields = self._get_fields
129
137
  search = @controller.request.query_parameters[@controller.class.search_query_param]
130
138
 
131
- # Ensure we use array conditions to prevent SQL injection.
132
- if search.present? && !fields.empty?
133
- return data.where(
134
- fields.map { |f|
135
- "CAST(#{f} AS VARCHAR) #{@controller.class.search_ilike ? "ILIKE" : "LIKE"} ?"
136
- }.join(" OR "),
137
- *(["%#{search}%"] * fields.length),
138
- )
139
+ if search.present?
140
+ if fields = self._get_fields.presence
141
+ # Ensure we pass user input as arguments to prevent SQL injection.
142
+ return data.where(
143
+ fields.map { |f|
144
+ "CAST(#{f} AS VARCHAR) #{@controller.class.search_ilike ? "ILIKE" : "LIKE"} ?"
145
+ }.join(" OR "),
146
+ *(["%#{search}%"] * fields.length),
147
+ )
148
+ end
139
149
  end
140
150
 
141
151
  return data
@@ -1,6 +1,5 @@
1
1
  module RESTFramework::Utils
2
2
  HTTP_METHOD_ORDERING = %w(GET POST PUT PATCH DELETE OPTIONS HEAD)
3
- LABEL_FIELDS = %w(name label login title email username url)
4
3
 
5
4
  # Convert `extra_actions` hash to a consistent format: `{path:, methods:, kwargs:}`, and
6
5
  # additional metadata fields.
@@ -186,14 +185,15 @@ module RESTFramework::Utils
186
185
  def self.sub_fields_for(ref)
187
186
  if !ref.polymorphic? && model = ref.klass
188
187
  sub_fields = [model.primary_key].flatten.compact
188
+ label_fields = RESTFramework.config.label_fields
189
189
 
190
190
  # Preferrably find a database column to use as label.
191
- if match = LABEL_FIELDS.find { |f| f.in?(model.column_names) }
191
+ if match = label_fields.find { |f| f.in?(model.column_names) }
192
192
  return sub_fields + [match]
193
193
  end
194
194
 
195
195
  # Otherwise, find a method.
196
- if match = LABEL_FIELDS.find { |f| model.method_defined?(f) }
196
+ if match = label_fields.find { |f| model.method_defined?(f) }
197
197
  return sub_fields + [match]
198
198
  end
199
199
 
@@ -26,6 +26,8 @@ module RESTFramework
26
26
  ActiveStorage::Attachment
27
27
  ActiveStorage::Blob
28
28
  ).freeze
29
+ DEFAULT_LABEL_FIELDS = %w(name label login title email username url).freeze
30
+ DEFAULT_SEARCH_COLUMNS = DEFAULT_LABEL_FIELDS + %w(description note).freeze
29
31
 
30
32
  # Do not run `rrf_finalize` on controllers automatically using a `TracePoint` hook. This is a
31
33
  # performance option and must be global because we have to determine this before any
@@ -50,12 +52,20 @@ module RESTFramework
50
52
  # Option to disable `rescue_from` on the controller mixins.
51
53
  attr_accessor :disable_rescue_from
52
54
 
53
- # Options to exclude certain classes from being added by default as association fields.
55
+ # Option to exclude certain classes from being added by default as association fields.
54
56
  attr_accessor :exclude_association_classes
55
57
 
58
+ # Option for the default label fields to use when generating labels for `has_many` associations.
59
+ attr_accessor :label_fields
60
+
61
+ # Option for the default search columns to use when generating search filters.
62
+ attr_accessor :search_columns
63
+
56
64
  def initialize
57
65
  self.show_backtrace = Rails.env.development?
58
66
  self.exclude_association_classes = DEFAULT_EXCLUDE_ASSOCIATION_CLASSES
67
+ self.label_fields = DEFAULT_LABEL_FIELDS
68
+ self.search_columns = DEFAULT_SEARCH_COLUMNS
59
69
  end
60
70
  end
61
71
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest_framework
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregory N. Schmit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-25 00:00:00.000000000 Z
11
+ date: 2023-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails