Method: Praxis::Extensions::AttributeFiltering::ActiveRecordFilterQueryBuilder.add_clause

Defined in:
lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb

.add_clause(query:, column_prefix:, column_object:, op:, value:, fuzzy:, association_key_column:) ⇒ Object

rubocop:disable Metrics/ParameterLists,Naming/MethodParameterName



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb', line 143

def self.add_clause(query:, column_prefix:, column_object:, op:, value:, fuzzy:, association_key_column:)
  likeval = get_like_value(value, fuzzy)

  association_op = nil
  case op
  when '!' # name! means => name IS NOT NULL (and the incoming value is nil)
    op = '!='
    value = nil # Enforce it is indeed nil (should be)
    association_op = :not_null if association_key_column && !column_object
  when '!!'
    op = '='
    value = nil # Enforce it is indeed nil (should be)
    association_op = :null if association_key_column && !column_object
  end

  if association_op
    neg = association_op == :not_null
    qr = quote_right_part(query: query, value: nil, column_object: association_key_column, negative: neg)
    return query.where("#{quote_column_path(query: query, prefix: column_prefix, column_name: association_key_column.name)} #{qr}")
  end

  # Add an AND along with the condition, which ensures the left outter join 'exists' for it
  # Normally this wouldn't be necessary as a condition on a given value mathing would imply the related row was there
  # but this is not the case for NULL conditions, as the foreign column would match a  NULL value, but not because the related column
  # is NULL, but because the whole missing related row would appear with all fields null
  # NOTE: we don't need to do it for conditions applying to the root of the tree (there isn't a join to it)
  if association_key_column
    qr = quote_right_part(query: query, value: nil, column_object: association_key_column, negative: true)
    query = query.where("#{quote_column_path(query: query, prefix: column_prefix, column_name: association_key_column.name)} #{qr}")
  end

  case op
  when '='
    if likeval
      add_safe_where(query: query, tab: column_prefix, col: column_object, op: 'LIKE', value: likeval)
    else
      quoted_right = quote_right_part(query: query, value: value, column_object: column_object, negative: false)
      query.where("#{quote_column_path(query: query, prefix: column_prefix, column_name: column_object.name)} #{quoted_right}")
    end
  when '!='
    if likeval
      add_safe_where(query: query, tab: column_prefix, col: column_object, op: 'NOT LIKE', value: likeval)
    else
      quoted_right = quote_right_part(query: query, value: value, column_object: column_object, negative: true)
      query.where("#{quote_column_path(query: query, prefix: column_prefix, column_name: column_object.name)} #{quoted_right}")
    end
  when '>'
    add_safe_where(query: query, tab: column_prefix, col: column_object, op: '>', value: value)
  when '<'
    add_safe_where(query: query, tab: column_prefix, col: column_object, op: '<', value: value)
  when '>='
    add_safe_where(query: query, tab: column_prefix, col: column_object, op: '>=', value: value)
  when '<='
    add_safe_where(query: query, tab: column_prefix, col: column_object, op: '<=', value: value)
  else
    raise "Unsupported Operator!!! #{op}"
  end
end