Class: Collate::Filter

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

Constant Summary collapse

OPERATORS =
[:eq, :ilike, :in, :le, :ge, :null, :contains, :present?, :&, :like]
FIELD_TRANSFORMATIONS =
[:date_difference, :date_part, :array_agg, :downcase, :split, :array_length]
AGGREGATE_TRANSFORMATIONS =
[:array_agg]
VALUE_TRANSFORMATIONS =
[:join, :downcase, :string_part, :to_json]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(field, opt = {}) ⇒ Filter

Returns a new instance of Filter.



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
40
41
42
43
44
45
46
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/collate/filter.rb', line 13

def initialize(field, opt={})
  opt.each do |f, value|
    self.send("#{f}=", value)
  end

  self.component ||= {}

  self.field = field
  self.label ||= field.to_s.titleize
  self.operator ||= if field.to_s.last(3) == '.id' || field.to_s.last(3) == '_id'
    :in
  elsif self.component[:type] == 'checkboxgroup'
    :in
  else
    :eq
  end
  self.field = "#{base_model_table_name}.#{field}" if field.is_a? Symbol
  self.field_transformations ||= []
  self.value_transformations ||= []

  field_parts = self.field.to_s.partition('.')
  table_name = field_parts[0]
  field_selector = field_parts[2]

  self.component = if self.operator == :in
    self.component.reverse_merge({type: 'select', multiple: true, values: []})
  elsif self.operator == :null || self.operator == :present?
    self.component.reverse_merge({type: 'checkbox'})
  elsif self.component[:tags]
    self.component.reverse_merge({type: 'select', multiple: true})
  else
    self.component.reverse_merge({type: 'string'})
  end

  if self.component[:load_records]
    model_name = if field_selector.last(3) == '_id'
      field_selector.chomp(field_selector.last(3))
    elsif self.field.to_s.last(3) == '.id'
      table_name.singularize
    else
      table_name.singularize
    end

    self.component[:load_record_model] ||= model_name.titleize
    self.component[:load_record_field] ||= "id"
    self.component[:load_record_route] ||= "/#{model_name.pluralize}.json"
    self.component[:load_record_text_method] ||= "name"
  end

  self.joins ||= if table_name != base_model_table_name
    join_name = table_name.to_sym
    base_model_table_name.singularize.titleize.constantize.reflect_on_all_associations.each do |assoc|

      join_name = assoc.name if assoc.plural_name == table_name
    end

    [join_name.to_sym]
  end
  self.joins_prefix = [self.joins_prefix] if self.joins_prefix.is_a? String

  if !opt.has_key?(:having) && (field_transformations.to_a.flatten & AGGREGATE_TRANSFORMATIONS).any?
    self.having = true
  end

  if self.value_transformations.empty? && self.operator == :ilike
    self.value_transformations = [:string_part]
  end

  self.grouping ||= if self.having
    "#{base_model_table_name}.id"
  end

  if self.component[:values]
    self.component[:values] = if self.component[:values].is_a?(Array) && self.component[:values].all? { |item| item.is_a? String }
      self.component[:values].map { |s| {id: s, text: s.titleize} }
    elsif self.component[:values].is_a?(Array) && self.component[:values].all? { |item| item.is_a? Symbol }
      self.component[:values].map { |s| {id: s, text: s.to_s.titleize} }
    elsif self.component[:values].respond_to?(:<) && self.component[:values] < ActiveRecord::Base
      self.component[:values].table_exists? ? self.component[:values].all.map { |m| {id: m.id, text: m.name} } : []
    else
      self.component[:values]
    end
  elsif component[:tags]
    self.component[:values] = []
  end

  ## MySQL support
  if Collate::database_type == :mysql2
    # Translate all ILIKE operators to LIKE operators while downcasing values
    if self.operator == :ilike
      self.operator = :like
      self.field_transformations << [:downcase]
      self.value_transformations << [:downcase]
    end
  end

  self.param_key ||= generate_param_key

  self.html_id ||= param_key.gsub('{','').gsub('}','').gsub('.','_').gsub(',','_')
end

Instance Attribute Details

#base_model_table_nameObject

Returns the value of attribute base_model_table_name.



9
10
11
# File 'lib/collate/filter.rb', line 9

def base_model_table_name
  @base_model_table_name
end

#componentObject

Returns the value of attribute component.



9
10
11
# File 'lib/collate/filter.rb', line 9

def component
  @component
end

#fieldObject

Returns the value of attribute field.



9
10
11
# File 'lib/collate/filter.rb', line 9

def field
  @field
end

#field_group_typeObject

Returns the value of attribute field_group_type.



9
10
11
# File 'lib/collate/filter.rb', line 9

def field_group_type
  @field_group_type
end

#field_transformationsObject

Returns the value of attribute field_transformations.



9
10
11
# File 'lib/collate/filter.rb', line 9

def field_transformations
  @field_transformations
end

#groupingObject

Returns the value of attribute grouping.



9
10
11
# File 'lib/collate/filter.rb', line 9

def grouping
  @grouping
end

#havingObject

Returns the value of attribute having.



9
10
11
# File 'lib/collate/filter.rb', line 9

def having
  @having
end

#html_idObject

Returns the value of attribute html_id.



9
10
11
# File 'lib/collate/filter.rb', line 9

def html_id
  @html_id
end

#joinsObject

Returns the value of attribute joins.



9
10
11
# File 'lib/collate/filter.rb', line 9

def joins
  @joins
end

#joins_prefixObject

Returns the value of attribute joins_prefix.



9
10
11
# File 'lib/collate/filter.rb', line 9

def joins_prefix
  @joins_prefix
end

#labelObject

Returns the value of attribute label.



9
10
11
# File 'lib/collate/filter.rb', line 9

def label
  @label
end

#notObject

Returns the value of attribute not.



9
10
11
# File 'lib/collate/filter.rb', line 9

def not
  @not
end

#operatorObject

Returns the value of attribute operator.



9
10
11
# File 'lib/collate/filter.rb', line 9

def operator
  @operator
end

#orObject

Returns the value of attribute or.



9
10
11
# File 'lib/collate/filter.rb', line 9

def or
  @or
end

#param_keyObject

Returns the value of attribute param_key.



9
10
11
# File 'lib/collate/filter.rb', line 9

def param_key
  @param_key
end

#value_transformationsObject

Returns the value of attribute value_transformations.



9
10
11
# File 'lib/collate/filter.rb', line 9

def value_transformations
  @value_transformations
end

Instance Method Details

#generate_param_keyObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/collate/filter.rb', line 114

def generate_param_key
  key = ""
  self.field_transformations.each do |ft|
    transformation = ft
    transformation = ft[0] if !transformation.is_a? Symbol
    key += FIELD_TRANSFORMATIONS.index(transformation).to_s
  end
  key += OPERATORS.index(operator).to_s
  self.value_transformations.each do |vt|
    transformation = vt
    transformation = vt[0] if !transformation.is_a? Symbol
    key += VALUE_TRANSFORMATIONS.index(transformation).to_s
    key += vt[1] if !vt.is_a? Symbol
  end

  "{#{key}}#{field.to_s.gsub('[','').gsub(']','').gsub('"','').gsub(',','').gsub(' ','_')}"
end