Sha256: 847709c48b2503eb3ba0905f71f1247bce0a73746ad894ce6875353b571c00b4
Contents?: true
Size: 1.5 KB
Versions: 5
Compression:
Stored size: 1.5 KB
Contents
# frozen_string_literal: true module Lipstick module Filterable # Provides case-insensitive matching on a case-sensitive MySQL database # (which is mandated by Gumboot) class CollatedArelAttribute < Arel::Nodes::Node include Arel::Predications attr_reader :attribute, :collation def initialize(attribute, collation) @attribute = attribute @collation = collation end end module VisitCollatedArelAttribute # rubocop:disable Naming/MethodName def visit_Lipstick_Filterable_CollatedArelAttribute(object, collector) visit(object.attribute, collector) collector << ' COLLATE ' << object.collation end # rubocop:enable Naming/MethodName end Arel::Visitors::ToSql.include(VisitCollatedArelAttribute) module ClassMethods attr_reader :filterable_fields def filterable_by(*fields) @filterable_fields = fields end def filterable_filter(query) filter_terms(query).reduce(all) do |scope, term| conds = filterable_fields.map do |f| CollatedArelAttribute.new(arel_table[f], 'utf8_unicode_ci') .matches(term) end scope.where(conds.reduce { |acc, elem| acc.or(elem) }) end end private def filter_terms(query) query.to_s.downcase.split(/\s+/).map { |s| "*#{s}*".gsub(/[%*]+/, '%') } end end def self.included(base) base.extend(ClassMethods) end end end
Version data entries
5 entries across 5 versions & 1 rubygems