Donovan Daniels
b1c702e3cd
poorly tested but it worked well enough, I'm sure I'll be patching bugs over the next few weeks Also remove turbo because it sucks Also changed the way we handle hosts in dev
158 lines
4.2 KiB
Ruby
158 lines
4.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class ApplicationRecord < ActiveRecord::Base
|
|
primary_abstract_class
|
|
|
|
module ApiMethods
|
|
extend ActiveSupport::Concern
|
|
|
|
def as_json(options = {})
|
|
options ||= {}
|
|
options[:except] ||= []
|
|
options[:except] += hidden_attributes
|
|
|
|
options[:methods] ||= []
|
|
options[:methods] += method_attributes
|
|
|
|
super(options)
|
|
end
|
|
|
|
def serializable_hash(*args)
|
|
hash = super(*args)
|
|
hash.transform_keys { |key| key.delete("?") }
|
|
end
|
|
|
|
protected
|
|
|
|
def hidden_attributes
|
|
%i[uploader_ip_addr updater_ip_addr creator_ip_addr user_ip_addr ip_addr]
|
|
end
|
|
|
|
def method_attributes
|
|
[]
|
|
end
|
|
end
|
|
|
|
module UserMethods
|
|
def belongs_to_creator(options = {})
|
|
field = options.delete(:field) || :creator
|
|
class_eval do
|
|
belongs_to(field, **options.merge(class_name: "APIUser"))
|
|
before_validation(on: :create) do |rec|
|
|
rec.send("#{field}_id=", CurrentUser.id) if rec.send("#{field}_id").nil?
|
|
rec.send("#{field}_ip_addr=", CurrentUser.ip_addr) if rec.respond_to?(:"#{field}_ip_addr=") && rec.send("#{field}_ip_addr").nil?
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
module SearchMethods
|
|
def attribute_matches(attribute, value, **)
|
|
return all if value.nil?
|
|
|
|
column = column_for_attribute(attribute)
|
|
case column.sql_type_metadata.type
|
|
when :boolean
|
|
boolean_attribute_matches(attribute, value, **)
|
|
when :integer, :datetime
|
|
numeric_attribute_matches(attribute, value, **)
|
|
when :string, :text
|
|
text_attribute_matches(attribute, value, **)
|
|
else
|
|
raise(ArgumentError, "unhandled attribute type")
|
|
end
|
|
end
|
|
|
|
def boolean_attribute_matches(attribute, value)
|
|
if value.to_s.truthy?
|
|
value = true
|
|
elsif value.to_s.falsy?
|
|
value = false
|
|
else
|
|
raise(ArgumentError, "value must be truthy or falsy")
|
|
end
|
|
|
|
where(attribute => value)
|
|
end
|
|
|
|
# range: "5", ">5", "<5", ">=5", "<=5", "5..10", "5,6,7"
|
|
def numeric_attribute_matches(attribute, range)
|
|
column = column_for_attribute(attribute)
|
|
qualified_column = "#{table_name}.#{column.name}"
|
|
parsed_range = ParseValue.range(range, column.type)
|
|
|
|
add_range_relation(parsed_range, qualified_column)
|
|
end
|
|
|
|
def add_range_relation(arr, field)
|
|
return all if arr.nil?
|
|
|
|
case arr[0]
|
|
when :eq
|
|
if arr[1].is_a?(Time)
|
|
where("#{field} between ? and ?", arr[1].beginning_of_day, arr[1].end_of_day)
|
|
else
|
|
where(["#{field} = ?", arr[1]])
|
|
end
|
|
when :gt
|
|
where(["#{field} > ?", arr[1]])
|
|
when :gte
|
|
where(["#{field} >= ?", arr[1]])
|
|
when :lt
|
|
where(["#{field} < ?", arr[1]])
|
|
when :lte
|
|
where(["#{field} <= ?", arr[1]])
|
|
when :in
|
|
where(["#{field} in (?)", arr[1]])
|
|
when :between
|
|
where(["#{field} BETWEEN ? AND ?", arr[1], arr[2]])
|
|
else
|
|
all
|
|
end
|
|
end
|
|
|
|
def text_attribute_matches(attribute, value, convert_to_wildcard: false)
|
|
column = column_for_attribute(attribute)
|
|
qualified_column = "#{table_name}.#{column.name}"
|
|
value = "*#{value}*" if convert_to_wildcard && value.exclude?("*")
|
|
|
|
if value =~ /\*/
|
|
where("lower(#{qualified_column}) LIKE :value ESCAPE E'\\\\'", value: value.downcase.to_escaped_for_sql_like)
|
|
else
|
|
where("to_tsvector(:ts_config, #{qualified_column}) @@ plainto_tsquery(:ts_config, :value)", ts_config: "english", value: value)
|
|
end
|
|
end
|
|
|
|
def apply_basic_order(params)
|
|
case params[:order]
|
|
when "id_asc"
|
|
order(id: :asc)
|
|
when "id_desc"
|
|
order(id: :desc)
|
|
else
|
|
default_order
|
|
end
|
|
end
|
|
|
|
def default_order
|
|
order(id: :desc)
|
|
end
|
|
|
|
def search(params)
|
|
params ||= {}
|
|
|
|
q = all
|
|
q = q.attribute_matches(:id, params[:id])
|
|
q = q.attribute_matches(:category, params[:category])
|
|
q = q.attribute_matches(:created_at, params[:created_at]) if attribute_names.include?("created_at")
|
|
q = q.attribute_matches(:updated_at, params[:updated_at]) if attribute_names.include?("updated_at")
|
|
|
|
q
|
|
end
|
|
end
|
|
|
|
include ApiMethods
|
|
extend SearchMethods
|
|
extend UserMethods
|
|
end
|