Websites/app/models/application_record.rb
Donovan Daniels b1c702e3cd
Add image management ui
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
2024-05-06 03:25:17 -05:00

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