277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
|
# File 'app/models/effective/resources/relation.rb', line 277
def search_attribute(name, value, as:, operation:, sql_column:)
raise 'expected relation to be present' unless relation
attribute = relation.arel_table[name]
term = Attribute.new(as).parse(value, name: name)
term = value if term.nil?
joined = (sql_column.to_s.split('.').first.to_s.include?(relation.arel_table.name) == false)
searched = case as
when :active_storage
relation.send("with_attached_#{name}").references("#{name}_attachment")
.where(ActiveStorage::Blob.arel_table[:filename].matches("%#{term}%"))
when :date, :datetime
if value.kind_of?(String)
end_at = (
case (value.to_s.scan(/(\d+)/).flatten).length
when 1 ; term.end_of_year when 2 ; term.end_of_month when 3 ; term.end_of_day when 4 ; term.end_of_hour when 5 ; term.end_of_minute when 6 ; term + 1.second else term
end
)
if as == :date
term = term.to_date
end_at = end_at.to_date
end
relation.where("#{sql_column} >= ? AND #{sql_column} <= ?", term, end_at)
elsif value.respond_to?(:strftime) && operation == :eq
relation.where(attribute.matches(value))
end
when :effective_obfuscation
term = Attribute.new(as, klass: (associated(name).try(:klass) || klass)).parse(value, name: name)
relation.where(attribute.eq((value == term ? 0 : term)))
when :effective_addresses
association = associated(name)
associated = Resource.new(association).search_any(value)
relation.where(id: associated.where(addressable_type: klass.name).select(:addressable_id))
when :effective_roles
relation.with_role(term)
when :time
timed = relation.where("EXTRACT(hour from #{sql_column}) = ?", term.utc.hour)
timed = timed.where("EXTRACT(minute from #{sql_column}) = ?", term.utc.min) if term.min > 0
timed
end
return searched if searched
case operation
when :eq then relation.where("#{sql_column} = ?", term)
when :matches then relation.where("#{sql_column} #{ilike} ?", "%#{term}%")
when :not_eq then relation.where(attribute.not_eq(term))
when :does_not_match then relation.where(attribute.does_not_match("%#{term}%"))
when :starts_with then relation.where(attribute.matches("#{term}%"))
when :ends_with then relation.where(attribute.matches("%#{term}"))
when :gt then relation.where(attribute.gt(term))
when :gteq then relation.where(attribute.gteq(term))
when :lt then relation.where(attribute.lt(term))
when :lteq then relation.where(attribute.lteq(term))
else raise("Unexpected operation: #{operation}")
end
end
|