Class: RESTFramework::Filters::SearchFilter
- Inherits:
-
BaseFilter
- Object
- BaseFilter
- RESTFramework::Filters::SearchFilter
- Defined in:
- lib/rest_framework/filters/search_filter.rb
Instance Method Summary collapse
- #_get_fields ⇒ Object
-
#filter_data(data) ⇒ Object
Filter data according to the request query parameters.
Methods inherited from BaseFilter
#_polymorphic_columns, _safe_query_value?, #initialize
Constructor Details
This class inherits a constructor from RESTFramework::Filters::BaseFilter
Instance Method Details
#_get_fields ⇒ Object
2 3 4 5 6 7 |
# File 'lib/rest_framework/filters/search_filter.rb', line 2 def _get_fields # Always return a list of strings; `@controller.readable_columns` already does. @controller.class.search_fields&.map(&:to_s) || ( @controller.readable_columns & RESTFramework.config.search_columns ) end |
#filter_data(data) ⇒ Object
Filter data according to the request query parameters.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/rest_framework/filters/search_filter.rb', line 10 def filter_data(data) search = @controller.request.query_parameters[@controller.class.search_query_param] # Reject nested-hash inputs like `?search[evil]=x` (Rack parses these into a # Hash, which `sanitize_sql_like` can't accept). return data unless search.is_a?(String) if search.present? if fields = self._get_fields.presence # MySQL doesn't support casting to VARCHAR, so we need to use CHAR instead. data_type = if data.connection.adapter_name =~ /mysql|trilogy/i "CHAR" else # Sufficient for both PostgreSQL and SQLite. "VARCHAR" end conn = data.connection like_op = @controller.class.search_ilike ? "ILIKE" : "LIKE" return data.where( fields.map { |f| "CAST(#{conn.quote_column_name(f)} AS #{data_type}) #{like_op} ?" }.join(" OR "), *([ "%#{ActiveRecord::Base.sanitize_sql_like(search)}%" ] * fields.length), ) end end data end |