diff --git a/app/models/dossier_preloader.rb b/app/models/dossier_preloader.rb index 7c6dcd4ac7c..4eea0553405 100644 --- a/app/models/dossier_preloader.rb +++ b/app/models/dossier_preloader.rb @@ -37,18 +37,12 @@ def self.load_one(dossier, pj_template: false) private - def revisions + def revisions(pj_template: false) @revisions ||= ProcedureRevision.where(id: @dossiers.pluck(:revision_id).uniq) - .includes(types_de_champ: { piece_justificative_template_attachment: :blob }) + .includes(types_de_champ: pj_template ? { piece_justificative_template_attachment: :blob } : []) .index_by(&:id) end - # returns: { revision_id : { stable_id : position } } - def positions - @positions ||= revisions - .transform_values { |revision| revision.revision_types_de_champ.map { [_1.stable_id, _1.position] }.to_h } - end - def load_dossiers(dossiers, pj_template: false) to_include = @includes_for_champ.dup to_include << [piece_justificative_file_attachments: :blob] @@ -58,16 +52,10 @@ def load_dossiers(dossiers, pj_template: false) .where(dossier_id: dossiers) .to_a - children_champs, root_champs = all_champs.partition(&:child?) - champs_by_dossier = root_champs.group_by(&:dossier_id) - champs_by_dossier_by_parent = children_champs - .group_by(&:dossier_id) - .transform_values do |champs| - champs.group_by(&:parent_id) - end + champs_by_dossier = all_champs.group_by(&:dossier_id) dossiers.each do |dossier| - load_dossier(dossier, champs_by_dossier[dossier.id] || [], champs_by_dossier_by_parent[dossier.id] || {}) + load_dossier(dossier, champs_by_dossier[dossier.id] || [], pj_template:) end load_etablissements(all_champs) @@ -86,52 +74,36 @@ def load_etablissements(champs) end end - def load_dossier(dossier, champs, children_by_parent = {}) - revision = revisions[dossier.revision_id] + def load_dossier(dossier, champs, pj_template: false) + revision = revisions(pj_template:)[dossier.revision_id] if revision.present? dossier.association(:revision).target = revision end + dossier.association(:champs).target = champs + dossier.association(:champs_public).target = dossier.champs_for_revision(scope: :public, root: true) + dossier.association(:champs_private).target = dossier.champs_for_revision(scope: :private, root: true) - champs_public, champs_private = champs.partition(&:public?) - - dossier.association(:champs).target = [] - load_champs(dossier, :champs_public, champs_public, dossier, children_by_parent) - load_champs(dossier, :champs_private, champs_private, dossier, children_by_parent) - - # We need to do this because of the check on `Etablissement#champ` in - # `Etablissement#libelle_for_export`. By assigning `nil` to `target` we mark association - # as loaded and so the check on `Etablissement#champ` will not trigger n+1 query. - if dossier.etablissement - dossier.etablissement.association(:champ).target = nil - end - end - - def load_champs(parent, name, champs, dossier, children_by_parent) - if champs.empty? - parent.association(name).target = [] # tells to Rails association has been loaded - return - end + # remove once parent_id is deprecated + champs_by_parent_id = champs.group_by(&:parent_id) champs.each do |champ| champ.association(:dossier).target = dossier - if parent.is_a?(Champ) - champ.association(:parent).target = parent + # remove once parent_id is deprecated + if champ.repetition? + children = champs_by_parent_id.fetch(champ.id, []) + children.each do |child| + child.association(:parent).target = champ + end + champ.association(:champs).target = children end end - dossier.association(:champs).target += champs - - parent.association(name).target = champs - .filter { positions[dossier.revision_id][_1.stable_id].present? } - .sort_by { [_1.row_id, positions[dossier.revision_id][_1.stable_id]] } - - # Load children champs - champs.filter(&:block?).each do |parent_champ| - champs = children_by_parent[parent_champ.id] || [] - parent_champ.association(:dossier).target = dossier - - load_champs(parent_champ, :champs, champs, dossier, children_by_parent) + # We need to do this because of the check on `Etablissement#champ` in + # `Etablissement#libelle_for_export`. By assigning `nil` to `target` we mark association + # as loaded and so the check on `Etablissement#champ` will not trigger n+1 query. + if dossier.etablissement + dossier.etablissement.association(:champ).target = nil end end end