lib/torque/postgresql/associations/preloader/association.rb in torque-postgresql-2.4.5 vs lib/torque/postgresql/associations/preloader/association.rb in torque-postgresql-3.0.0

- old
+ new

@@ -9,14 +9,67 @@ delegate :connected_through_array?, to: :@reflection # For reflections connected through an array, make sure to properly # decuple the list of ids and set them as associated with the owner def run + return self if run? return super unless connected_through_array? + + @run = true send("run_array_for_#{@reflection.macro}") + self end + # Correctly correlate records when they are connected theough an array + def set_inverse(record) + return super unless connected_through_array? && @reflection.macro == :has_many + + # Only the first owner is associated following the same instruction + # on the original implementation + convert_key(record[association_key_name])&.each do |key| + if owners = owners_by_key[key] + association = owners.first.association(reflection.name) + association.set_inverse_instance(record) + end + end + end + + # Requires a slight change when running on has many since the value + # of the foreign key being an array + def load_records(raw_records = nil) + return super unless connected_through_array? && @reflection.macro == :has_many + + @records_by_owner = {}.compare_by_identity + raw_records ||= loader_query.records_for([self]) + + @preloaded_records = raw_records.select do |record| + assignments = false + + keys = convert_key(record[association_key_name]) || [] + owners_by_key.values_at(*keys).each do |owner| + entries = (@records_by_owner[owner] ||= []) + + if reflection.collection? || entries.empty? + entries << record + assignments = true + end + end + + assignments + end + end + + # Make sure to change the process when connected through an array + def owners_by_key + return super unless connected_through_array? + @owners_by_key ||= owners.each_with_object({}) do |owner, result| + Array.wrap(convert_key(owner[owner_key_name])).each do |key| + (result[key] ||= []) << owner + end + end + end + private # Specific run for belongs_many association def run_array_for_belongs_to_many # Add reverse to has_many @@ -36,35 +89,9 @@ end records.default_proc = nil owners.each do |owner| associate_records_to_owner(owner, records[owner[owner_key_name]] || []) - end - end - - if PostgreSQL::AR604 - # This is how Rails 6.0.4 and 6.1 now load the records - def load_records - return super unless connected_through_array? - - @records_by_owner = {}.compare_by_identity - raw_records = owner_keys.empty? ? [] : records_for(owner_keys) - - @preloaded_records = raw_records.select do |record| - assignments = false - - ids = convert_key(record[association_key_name]) - owners_by_key.values_at(*ids).flat_map do |owner| - entries = (@records_by_owner[owner] ||= []) - - if reflection.collection? || entries.empty? - entries << record - assignments = true - end - end - - assignments - end end end # Build correctly the constraint condition in order to get the # associated ids