From c60a8970f1873890c76d4e84e157d61092e547c0 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 10 Mar 2022 19:22:07 +0100 Subject: [PATCH] perf(dossier): memoize champ.sections on dossier --- app/models/champ.rb | 12 +----------- app/models/dossier.rb | 14 ++++++++++++++ spec/models/champ_spec.rb | 29 +++++++++++++++++++++-------- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/app/models/champ.rb b/app/models/champ.rb index b2aee8e41..9e06258d4 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -81,18 +81,8 @@ class Champ < ApplicationRecord !private? end - def siblings - if parent - parent&.champs - elsif public? - dossier&.champs - else - dossier&.champs_private - end - end - def sections - siblings&.filter(&:header_section?) + @sections ||= dossier.sections_for(self) end def mandatory_and_blank? diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 08f093c22..cb195c720 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -1122,6 +1122,20 @@ class Dossier < ApplicationRecord termine_expired_to_delete.find_each(&:purge_discarded) end + def sections_for(champ) + @sections = Hash.new do |hash, parent| + case parent + when :public + hash[parent] = champs.filter(&:header_section?) + when :private + hash[parent] = champs_private.filter(&:header_section?) + else + hash[parent] = parent.champs.filter(&:header_section?) + end + end + @sections[champ.parent || (champ.public? ? :public : :private)] + end + private def create_missing_traitemets diff --git a/spec/models/champ_spec.rb b/spec/models/champ_spec.rb index 1f8bbda18..b256a04d9 100644 --- a/spec/models/champ_spec.rb +++ b/spec/models/champ_spec.rb @@ -69,19 +69,32 @@ describe Champ do end end - describe '#siblings' do - let(:procedure) { create(:procedure, :with_type_de_champ, :with_type_de_champ_private, :with_repetition, types_de_champ_count: 1, types_de_champ_private_count: 1) } + describe '#sections' do + let(:procedure) do + create(:procedure, :with_type_de_champ, :with_type_de_champ_private, :with_repetition, types_de_champ_count: 1, types_de_champ_private_count: 1).tap do |procedure| + create(:type_de_champ_header_section, procedure: procedure) + create(:type_de_champ_header_section, procedure: procedure, private: true) + create(:type_de_champ_header_section, parent: procedure.types_de_champ.find(&:repetition?)) + end + end let(:dossier) { create(:dossier, procedure: procedure) } let(:public_champ) { dossier.champs.first } let(:private_champ) { dossier.champs_private.first } let(:champ_in_repetition) { dossier.champs.find(&:repetition?).champs.first } - let(:standalone_champ) { build(:champ, type_de_champ: build(:type_de_champ), dossier: nil) } + let(:standalone_champ) { build(:champ, type_de_champ: build(:type_de_champ), dossier: build(:dossier)) } + let(:public_sections) { dossier.champs.filter(&:header_section?) } + let(:private_sections) { dossier.champs_private.filter(&:header_section?) } + let(:sections_in_repetition) { champ_in_repetition.parent.champs.filter(&:header_section?) } - it 'returns the sibling champs of a champ' do - expect(public_champ.siblings).to eq(dossier.champs) - expect(private_champ.siblings).to eq(dossier.champs_private) - expect(champ_in_repetition.siblings).to eq(champ_in_repetition.parent.champs) - expect(standalone_champ.siblings).to be_nil + it 'returns the sibling sections of a champ' do + expect(public_sections).not_to be_empty + expect(private_sections).not_to be_empty + expect(sections_in_repetition).not_to be_empty + + expect(public_champ.sections).to eq(public_sections) + expect(private_champ.sections).to eq(private_sections) + expect(champ_in_repetition.sections).to eq(sections_in_repetition) + expect(standalone_champ.sections).to eq([]) end end