Merge pull request #7832 from betagouv/perf_dossier_save

perf(dossier_controller): améliore la performance d'affichage d'un dossier
This commit is contained in:
LeSim 2022-10-10 12:52:10 +02:00 committed by GitHub
commit 668f5a70f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 6 deletions

View file

@ -392,7 +392,7 @@ module Users
end
def dossier_with_champs
dossier_scope.with_champs.find(params[:id])
DossierPreloader.load_one(dossier)
end
def should_change_groupe_instructeur?

View file

@ -11,12 +11,16 @@ class DossierPreloader
dossiers
end
def all
def all(pj_template: false)
dossiers = @dossiers.to_a
load_dossiers(dossiers)
load_dossiers(dossiers, pj_template:)
dossiers
end
def self.load_one(dossier)
DossierPreloader.new([dossier]).all(pj_template: true).first
end
private
# returns: { revision_id : { type_de_champ_id : position } }
@ -30,9 +34,17 @@ class DossierPreloader
end
end
def load_dossiers(dossiers)
def load_dossiers(dossiers, pj_template: false)
to_include = [piece_justificative_file_attachment: :blob]
if pj_template
to_include << { type_de_champ: { piece_justificative_template_attachment: :blob } }
else
to_include << :type_de_champ
end
all_champs = Champ
.includes(:type_de_champ, piece_justificative_file_attachment: :blob)
.includes(to_include)
.where(dossier_id: dossiers)
.to_a
@ -80,6 +92,10 @@ class DossierPreloader
def load_champs(parent, name, champs, dossier, children_by_parent)
champs.each do |champ|
champ.association(:dossier).target = dossier
if parent.is_a?(Champ)
champ.association(:parent).target = parent
end
end
parent.association(name).target = champs.sort_by do |champ|
@ -92,7 +108,6 @@ class DossierPreloader
parent_champ.association(:dossier).target = dossier
load_champs(parent_champ, :champs, champs, dossier, children_by_parent)
parent_champ.association(:champs).set_inverse_instance(parent_champ)
end
end
end

View file

@ -0,0 +1,37 @@
describe DossierPreloader do
let(:types_de_champ) do
[
{ type: :text },
{ type: :repetition, children: [{ type: :text }] }
]
end
let(:procedure) { create(:procedure, types_de_champ_public: types_de_champ) }
let(:dossier) { create(:dossier, procedure: procedure) }
let(:repetition) { subject.champs.second }
let(:first_child) { subject.champs.second.champs.first }
describe 'all' do
subject { DossierPreloader.load_one(dossier) }
before { subject }
it do
count = 0
callback = lambda { |*_args| count += 1 }
ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do
expect(subject.id).to eq(dossier.id)
expect(subject.champs.size).to eq(types_de_champ.size)
expect(subject.changed?).to be false
expect(first_child.type).to eq('Champs::TextChamp')
expect(repetition.id).not_to eq(first_child.id)
expect(subject.champs.first.dossier).to eq(subject)
expect(subject.champs.first.type_de_champ.piece_justificative_template.attached?).to eq(false)
expect(first_child.parent).to eq(repetition)
end
expect(count).to eq(0)
end
end
end