105 lines
3.1 KiB
Ruby
105 lines
3.1 KiB
Ruby
# typed: false
|
|
# frozen_string_literal: true
|
|
|
|
module HasAuxTable
|
|
module QueryExtensions
|
|
extend T::Sig
|
|
|
|
# Split conditions into main table and aux table conditions
|
|
def split_conditions(conditions, aux_config)
|
|
main_conditions = {}
|
|
aux_conditions = {}
|
|
|
|
conditions.each do |key, value|
|
|
if aux_config.is_aux_column?(key)
|
|
aux_conditions[key] = value
|
|
else
|
|
main_conditions[key] = value
|
|
end
|
|
end
|
|
|
|
[main_conditions, aux_conditions]
|
|
end
|
|
|
|
sig do
|
|
params(
|
|
on: T.any(ActiveRecord::Relation, T.class_of(ActiveRecord::Base)),
|
|
aux_config: AuxTableConfig,
|
|
with_bind_attribute: T::Boolean
|
|
).void
|
|
end
|
|
def setup_query_extensions!(on, aux_config, with_bind_attribute: true)
|
|
association_name = aux_config.aux_association_name
|
|
|
|
on.define_singleton_method(:where) do |*args|
|
|
if args.first.is_a?(Hash)
|
|
relation = self.eager_load(association_name)
|
|
self.apply_split_conditions!(relation, args)
|
|
self.setup_query_extensions!(relation, aux_config)
|
|
relation
|
|
else
|
|
super(*args)
|
|
end
|
|
end
|
|
|
|
all_method = on.method(:all)
|
|
on.define_singleton_method(:all) do
|
|
all_method.call.eager_load(association_name)
|
|
end
|
|
|
|
unscoped_method = on.method(:unscoped)
|
|
on.define_singleton_method(:unscoped) do
|
|
relation = unscoped_method.call
|
|
self.setup_query_extensions!(relation, aux_config)
|
|
relation
|
|
end
|
|
|
|
if with_bind_attribute
|
|
bind_attribute_method = on.method(:bind_attribute)
|
|
on.define_singleton_method(:bind_attribute) do |name, value, &block|
|
|
if aux_config.is_aux_column?(name)
|
|
aux_config.aux_bind_attribute(name, value, &block)
|
|
else
|
|
bind_attribute_method.call(name, value, &block)
|
|
end
|
|
end
|
|
end
|
|
|
|
on.define_singleton_method(:find_by) do |*args|
|
|
relation = self.eager_load(association_name)
|
|
self.apply_split_conditions!(relation, args)
|
|
relation.first
|
|
end
|
|
|
|
on.define_singleton_method(:apply_split_conditions!) do |relation, args|
|
|
conditions = args.first
|
|
main_conditions, aux_conditions =
|
|
self.split_conditions(conditions, aux_config)
|
|
relation.where!(main_conditions) if main_conditions.any?
|
|
if aux_conditions.any?
|
|
relation.where!(association_name => aux_conditions)
|
|
end
|
|
end
|
|
|
|
on.define_singleton_method(:find) do |*args|
|
|
self.eager_load(association_name).find(*args)
|
|
end
|
|
|
|
on.define_singleton_method(:exists?) do |*args|
|
|
conditions = args.first || {}
|
|
main_conditions, aux_conditions =
|
|
self.split_conditions(conditions, aux_config)
|
|
puts "checking with conditions: #{main_conditions} / #{aux_conditions}"
|
|
|
|
relation = self.select("1").joins(association_name)
|
|
relation.where!(main_conditions) if main_conditions.any?
|
|
if aux_conditions.any?
|
|
relation.where!(association_name => aux_conditions)
|
|
end
|
|
|
|
relation.first.present?
|
|
end
|
|
end
|
|
end
|
|
end
|