Class: ApiMaker::PreloaderThrough
- Inherits:
-
Object
- Object
- ApiMaker::PreloaderThrough
- Defined in:
- lib/api_maker/preloader_through.rb
Instance Method Summary collapse
- #append_name_for_current_reflection(current_reflection) ⇒ Object
-
#initialize(collection:, reflection:) ⇒ PreloaderThrough
constructor
A new instance of PreloaderThrough.
- #joins_array_to_hash(array) ⇒ Object
- #joins_for_reflection(current_reflection) ⇒ Object
- #models_query_through_reflection ⇒ Object
- #next_reflection_for(current_reflection) ⇒ Object
- #resolve_through(current_reflection) ⇒ Object
Constructor Details
#initialize(collection:, reflection:) ⇒ PreloaderThrough
Returns a new instance of PreloaderThrough.
2 3 4 5 |
# File 'lib/api_maker/preloader_through.rb', line 2 def initialize(collection:, reflection:) @collection = collection @reflection = reflection end |
Instance Method Details
#append_name_for_current_reflection(current_reflection) ⇒ Object
55 56 57 58 59 60 61 62 63 |
# 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) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# 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) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# 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 ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 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) ⇒ Object
86 87 88 89 90 91 92 93 94 95 |
# 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) ⇒ Object
97 98 99 100 |
# 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 |