class ApiMaker::PreloaderThrough
Public Class Methods
new(collection:, reflection:)
click to toggle source
# File lib/api_maker/preloader_through.rb, line 2 def initialize(collection:, reflection:) @collection = collection @reflection = reflection end
Public Instance Methods
append_name_for_current_reflection(current_reflection)
click to toggle source
# File lib/api_maker/preloader_through.rb, line 55 def append_name_for_current_reflection(current_reflection) singular_name = current_reflection.__send__(:inverse_name)&.to_s || current_reflection.active_record.model_name.param_key return singular_name.to_sym if @reflection.klass.reflections.key?(singular_name) plural_name = singular_name.pluralize return plural_name.to_sym if @reflection.klass.reflections.key?(plural_name) raise "Couldn't find a reflection name #{singular_name} or #{plural_name} on #{@reflection.klass.name}" end
joins_array_to_hash(array)
click to toggle source
# File lib/api_maker/preloader_through.rb, line 65 def joins_array_to_hash(array) array = array.clone result = {} work_result = result while array.any? element = array.pop if array.length == 1 work_result[element] = array.pop else work_result[element] = {} end work_result = work_result[element] end result end
joins_for_reflection(current_reflection)
click to toggle source
# File lib/api_maker/preloader_through.rb, line 24 def joins_for_reflection(current_reflection) joins = [] loop do # Resolve if the through relationship is through multiple other through relationships current_reflection = resolve_through(current_reflection) macro = current_reflection.through_reflection.macro inverse_name = current_reflection.through_reflection.__send__(:inverse_name) if inverse_name joins << inverse_name elsif macro == :has_many joins << current_reflection.through_reflection.name elsif macro == :belongs_to || macro == :has_one joins << current_reflection.through_reflection.active_record.model_name.plural.to_sym else raise "Unknown class: #{current_reflection.through_reflection.class.name}" end current_reflection = next_reflection_for(current_reflection) unless current_reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) joins.append(append_name_for_current_reflection(current_reflection)) break end end joins end
models_query_through_reflection()
click to toggle source
# File lib/api_maker/preloader_through.rb, line 7 def models_query_through_reflection last_reflection = @reflection.through_reflection.inverse_of if last_reflection table_name = last_reflection.table_name primary_key = last_reflection.klass.primary_key else table_name = @reflection.through_reflection.active_record.model_name.plural primary_key = @reflection.through_reflection.active_record.primary_key end joins_hash = joins_array_to_hash(joins_for_reflection(@reflection)) @reflection.klass.joins(joins_hash) .where(table_name => {primary_key => @collection.map(&:id)}) end
next_reflection_for(current_reflection)
click to toggle source
# File lib/api_maker/preloader_through.rb, line 86 def next_reflection_for(current_reflection) reflection_name = (current_reflection.source_reflection_name || @reflection.name).to_s new_reflection = current_reflection.through_reflection.klass.reflections[reflection_name.pluralize] new_reflection ||= current_reflection.through_reflection.klass.reflections[reflection_name.singularize] raise "No such reflection: #{current_reflection.through_reflection.klass.name}##{reflection_name}" unless new_reflection new_reflection end
resolve_through(current_reflection)
click to toggle source
# File lib/api_maker/preloader_through.rb, line 97 def resolve_through(current_reflection) current_reflection = current_reflection.through_reflection while current_reflection.through_reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) current_reflection end