Class: CmAdmin::Models::Filter

Inherits:
Object
  • Object
show all
Defined in:
lib/cm_admin/models/filter.rb

Constant Summary collapse

VALID_FILTER_TYPES =
Set[:date, :multi_select, :range, :search, :single_select].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db_column_name:, filter_type:, options: {}) ⇒ Filter

Returns a new instance of Filter.

Raises:

  • (TypeError)


8
9
10
11
12
13
14
15
# File 'lib/cm_admin/models/filter.rb', line 8

def initialize(db_column_name:, filter_type:, options: {})
  raise TypeError, "Can't have array of multiple columns for #{filter_type} filter" if db_column_name.is_a?(Array) && db_column_name.size > 1 && !filter_type.to_sym.eql?(:search)
  raise ArgumentError, "Kindly select a valid filter type like #{VALID_FILTER_TYPES.sort.to_sentence(last_word_connector: ', or ')} instead of #{filter_type} for column #{db_column_name}" unless VALID_FILTER_TYPES.include?(filter_type.to_sym)
  @db_column_name, @filter_type = structure_data(db_column_name, filter_type)
  options.each do |key, value|
    self.send("#{key.to_s}=", value)
  end
end

Instance Attribute Details

#collectionObject

Returns the value of attribute collection.



4
5
6
# File 'lib/cm_admin/models/filter.rb', line 4

def collection
  @collection
end

#db_column_nameObject

Returns the value of attribute db_column_name.



4
5
6
# File 'lib/cm_admin/models/filter.rb', line 4

def db_column_name
  @db_column_name
end

#filter_typeObject

Returns the value of attribute filter_type.



4
5
6
# File 'lib/cm_admin/models/filter.rb', line 4

def filter_type
  @filter_type
end

#placeholderObject

Returns the value of attribute placeholder.



4
5
6
# File 'lib/cm_admin/models/filter.rb', line 4

def placeholder
  @placeholder
end

Class Method Details

.cm_date_and_range_filter(scope_value, records, filters) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/cm_admin/models/filter.rb', line 86

def cm_date_and_range_filter(scope_value, records, filters)
  return nil if scope_value.nil?
  scope_value.each do |key, value|
    if value.present?
      value = value.split(' to ')
      from = value[0].presence
      to = value[1].presence
      records = records.where(key => from..to)
    end
  end
  records
end

.cm_dropdown_filter(scope_value, records, filters) ⇒ Object



99
100
101
102
103
104
105
# File 'lib/cm_admin/models/filter.rb', line 99

def cm_dropdown_filter(scope_value, records, filters)
  return nil if scope_value.nil?
  scope_value.each do |key, value|
    records = records.where(key => value) if value.present?
  end
  records
end

.cm_search_filter(scope_value, records, filters) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/cm_admin/models/filter.rb', line 47

def cm_search_filter(scope_value, records, filters)
  return nil if scope_value.blank?
  table_name = records.table_name
  filters.select{|x| x if x.filter_type.eql?(:search)}.each do |filter|
    query_variables = []
    filter.db_column_name.each do |col|
      if col.is_a?(Symbol)
        query_variables << "#{table_name.pluralize}.#{col}"
      elsif col.is_a?(Hash)
        col.map do |key, value|
          value.map {|val| query_variables << "#{key.to_s.pluralize}.#{val}" }
        end
      end
    end
    terms = scope_value.downcase.split(/\s+/)
    terms = terms.map { |e|
      (e.gsub('*', '%').prepend('%') + '%').gsub(/%+/, '%')
    }
    sql = ""
    query_variables.each.with_index do |column, i|
      sql.concat("#{column} ILIKE ?")
      sql.concat(' OR ') unless query_variables.size.eql?(i+1)
    end

    if filter.db_column_name.map{|x| x.is_a?(Hash)}.include?(true)
      associations_hash = filter.db_column_name.select{|x| x if x.is_a?(Hash)}.last
      records = records.joins(associations_hash.keys)
    end

    records = records.where(
      terms.map { |term|
        sql
      }.join(' AND '),
      *terms.map { |e| [e] * query_variables.size }.flatten
    )
  end
  records
end

.filtered_data(filter_params, records, filters) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/cm_admin/models/filter.rb', line 31

def filtered_data(filter_params, records, filters)
  if filter_params
    filter_params.each do |scope_type, scope_value|
      scope_name = if scope_type.eql?('date') || scope_type.eql?('range')
        'date_and_range'
      elsif scope_type.eql?('single_select') || scope_type.eql?('multi_select')
        'dropdown'
      else
        scope_type
      end
      records = self.send("cm_#{scope_name}_filter", scope_value, records, filters) if scope_value.present?
    end
  end
  records
end

Instance Method Details

#structure_data(db_column_name, filter_type) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/cm_admin/models/filter.rb', line 17

def structure_data(db_column_name, filter_type)
  filter_type = filter_type.is_a?(Array) ? filter_type[0].to_sym : filter_type.to_sym

  case filter_type
  when :search
    db_column_name = (Array.new << db_column_name).flatten.map{|x| x.class.eql?(Hash) ? x : x.to_sym}
  else
    db_column_name = db_column_name.is_a?(Array) ? db_column_name[0].to_sym : db_column_name.to_sym
  end
  [db_column_name, filter_type]
end