Sha256: a818d0f2f253a31b4ab5a8c177b04bbf03af710335b1d773952d4e7ea4bf1421
Contents?: true
Size: 1.78 KB
Versions: 33
Compression:
Stored size: 1.78 KB
Contents
# frozen_string_literal: true module Motor module ApiQuery module Search SELECT_COLUMNS_AMOUNT = 2 COLUMN_TYPES = BuildSchema::SEARCHABLE_COLUMN_TYPES ID_REGEXP = /\A\d+\z/.freeze module_function def call(rel, keyword) return rel if keyword.blank? filters = fetch_filters(rel, keyword) arel_where = build_arel_or_query(filters) rel.where(arel_where) end def fetch_filters(rel, keyword) arel_filters = [] klass = rel.klass arel_table = klass.arel_table arel_filters << arel_table[klass.primary_key].eq(keyword) if keyword.match?(ID_REGEXP) string_column_names = find_searchable_columns(klass) selected_columns = select_columns(string_column_names) selected_columns.each { |name| arel_filters << arel_table[name].matches("%#{keyword}%") } arel_filters end def build_arel_or_query(filter_array) filter_array.reduce(nil) do |acc, filter| next acc = filter unless acc acc.or(filter) end end def select_columns(columns) selected_columns = columns.select do |name| BuildSchema::FindDisplayColumn::DISPLAY_NAME_REGEXP.match?(name) end.presence selected_columns ||= columns.first(SELECT_COLUMNS_AMOUNT) selected_columns end def find_searchable_columns(model) model.columns.map do |column| next unless column.type.in?(COLUMN_TYPES) has_inclusion_validator = model.validators_on(column.name).any? do |e| e.is_a?(ActiveModel::Validations::InclusionValidator) end next if has_inclusion_validator column.name end.compact end end end end
Version data entries
33 entries across 33 versions & 1 rubygems