perf(dossier): memoize champ.sections on dossier

This commit is contained in:
Paul Chavard 2022-03-10 19:22:07 +01:00
parent 51af70639b
commit c60a8970f1
3 changed files with 36 additions and 19 deletions

View file

@ -81,18 +81,8 @@ class Champ < ApplicationRecord
!private? !private?
end end
def siblings
if parent
parent&.champs
elsif public?
dossier&.champs
else
dossier&.champs_private
end
end
def sections def sections
siblings&.filter(&:header_section?) @sections ||= dossier.sections_for(self)
end end
def mandatory_and_blank? def mandatory_and_blank?

View file

@ -1122,6 +1122,20 @@ class Dossier < ApplicationRecord
termine_expired_to_delete.find_each(&:purge_discarded) termine_expired_to_delete.find_each(&:purge_discarded)
end 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 private
def create_missing_traitemets def create_missing_traitemets

View file

@ -69,19 +69,32 @@ describe Champ do
end end
end end
describe '#siblings' do describe '#sections' 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) } 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(:dossier) { create(:dossier, procedure: procedure) }
let(:public_champ) { dossier.champs.first } let(:public_champ) { dossier.champs.first }
let(:private_champ) { dossier.champs_private.first } let(:private_champ) { dossier.champs_private.first }
let(:champ_in_repetition) { dossier.champs.find(&:repetition?).champs.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 it 'returns the sibling sections of a champ' do
expect(public_champ.siblings).to eq(dossier.champs) expect(public_sections).not_to be_empty
expect(private_champ.siblings).to eq(dossier.champs_private) expect(private_sections).not_to be_empty
expect(champ_in_repetition.siblings).to eq(champ_in_repetition.parent.champs) expect(sections_in_repetition).not_to be_empty
expect(standalone_champ.siblings).to be_nil
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
end end