remove extra Dossier call in projection

This commit is contained in:
simon lehericey 2021-04-26 10:35:22 +02:00
parent fd6f110210
commit 7b94c2de88
6 changed files with 68 additions and 29 deletions

View file

@ -1,5 +1,5 @@
class DossierProjectionService
class DossierProjection < Struct.new(:dossier, :columns)
class DossierProjection < Struct.new(:dossier_id, :state, :archived, :columns)
end
TABLE = 'table'
@ -18,7 +18,10 @@ class DossierProjectionService
# - the order of the intermediary query results are unknown
# - some values can be missing (if a revision added or removed them)
def self.project(dossiers_ids, fields)
fields
state_field = { TABLE => 'self', COLUMN => 'state' }
archived_field = { TABLE => 'self', COLUMN => 'archived' }
([state_field, archived_field] + fields) # the view needs state and archived dossier attributes
.each { |f| f[:id_value_h] = {} }
.group_by { |f| f[TABLE] } # one query per table
.each do |table, fields|
@ -40,7 +43,15 @@ class DossierProjectionService
Dossier
.where(id: dossiers_ids)
.pluck(:id, *fields.map { |f| f[COLUMN].to_sym })
.each { |id, *columns| fields.zip(columns).each { |field, value| field[:id_value_h][id] = value&.strftime('%d/%m/%Y') } }
.each do |id, *columns|
fields.zip(columns).each do |field, value|
if [state_field, archived_field].include?(field)
field[:id_value_h][id] = value
else
field[:id_value_h][id] = value&.strftime('%d/%m/%Y') # other fields are datetime
end
end
end
when 'individual'
Individual
.where(dossier_id: dossiers_ids)
@ -74,11 +85,13 @@ class DossierProjectionService
end
end
Dossier
.select(:id, :state, :archived) # the dossier object is needed in the view
.find(dossiers_ids) # keeps dossiers_ids order and raise exception if one is missing
.map do |dossier|
DossierProjection.new(dossier, fields.map { |f| f[:id_value_h][dossier.id] })
dossiers_ids.map do |dossier_id|
DossierProjection.new(
dossier_id,
state_field[:id_value_h][dossier_id],
archived_field[:id_value_h][dossier_id],
fields.map { |f| f[:id_value_h][dossier_id] }
)
end
end
end

View file

@ -23,7 +23,13 @@
- else
%p.menu-item Le téléchargement des pièces jointes est désactivé pour les dossiers de plus de #{number_to_human_size Dossier::TAILLE_MAX_ZIP}.
= render partial: "instructeurs/procedures/dossier_actions", locals: { procedure: dossier.procedure, dossier: dossier, dossier_is_followed: current_instructeur&.follow?(dossier) }
= render partial: "instructeurs/procedures/dossier_actions",
locals: { procedure_id: dossier.procedure.id,
dossier_id: dossier.id,
state: dossier.state,
archived: dossier.archived,
dossier_is_followed: current_instructeur&.follow?(dossier) }
.state-button
= render partial: "state_button", locals: { dossier: dossier }

View file

@ -1,19 +1,19 @@
- if dossier.en_construction_ou_instruction?
- if Dossier::EN_CONSTRUCTION_OU_INSTRUCTION.include?(state)
- if dossier_is_followed
= link_to unfollow_instructeur_dossier_path(procedure, dossier), method: :patch, class: 'button' do
= link_to unfollow_instructeur_dossier_path(procedure_id, dossier_id), method: :patch, class: 'button' do
%span.icon.unfollow>
Ne plus suivre
- else
= link_to follow_instructeur_dossier_path(procedure, dossier), method: :patch, class: 'button' do
= link_to follow_instructeur_dossier_path(procedure_id, dossier_id), method: :patch, class: 'button' do
%span.icon.follow>
Suivre le dossier
- elsif dossier.termine?
- if dossier.archived
= link_to unarchive_instructeur_dossier_path(procedure, dossier), method: :patch, class: 'button' do
- elsif Dossier::TERMINE.include?(state)
- if archived
= link_to unarchive_instructeur_dossier_path(procedure_id, dossier_id), method: :patch, class: 'button' do
%span.icon.unarchive>
Désarchiver le dossier
- else
= link_to archive_instructeur_dossier_path(procedure, dossier), method: :patch, class: 'button' do
= link_to archive_instructeur_dossier_path(procedure_id, dossier_id), method: :patch, class: 'button' do
%span.icon.archive>
Archiver le dossier

View file

@ -131,27 +131,32 @@
%tbody
- @projected_dossiers.each do |p|
- dossier = p.dossier
- path = instructeur_dossier_path(@procedure, dossier.id)
- path = instructeur_dossier_path(@procedure, p.dossier_id)
%tr
%td.folder-col
%a.cell-link{ href: path }
%span.icon.folder
- if @not_archived_notifications_dossier_ids.include?(dossier.id)
- if @not_archived_notifications_dossier_ids.include?(p.dossier_id)
%span.notifications{ 'aria-label': 'notifications' }
%td.number-col
%a.cell-link{ href: path }= dossier.id
%a.cell-link{ href: path }= p.dossier_id
- p.columns.each do |column|
%td
%a.cell-link{ href: path }= column
%td.status-col
%a.cell-link{ href: path }= status_badge(dossier.state)
%a.cell-link{ href: path }= status_badge(p.state)
%td.action-col.follow-col= render partial: 'dossier_actions',
locals: { procedure_id: @procedure.id,
dossier_id: p.dossier_id,
state: p.state,
archived: p.archived,
dossier_is_followed: @followed_dossiers_id.include?(p.dossier_id) }
%td.action-col.follow-col= render partial: 'dossier_actions', locals: { procedure: @procedure, dossier: dossier, dossier_is_followed: @followed_dossiers_id.include?(dossier.id) }
= pagination
- else
%h2.empty-text Aucun dossier

View file

@ -31,6 +31,12 @@
%td.status-col
= link_to(dossier_linked_path(current_instructeur, dossier), class: 'cell-link') do
= status_badge(dossier.state)
%td.action-col.follow-col= render partial: 'instructeurs/procedures/dossier_actions', locals: { procedure: dossier.procedure, dossier: dossier, dossier_is_followed: @followed_dossiers_id.include?(dossier.id) }
%td.action-col.follow-col= render partial: "instructeurs/procedures/dossier_actions",
locals: { procedure_id: dossier.procedure.id,
dossier_id: dossier.id,
state: dossier.state,
archived: dossier.archived,
dossier_is_followed: @followed_dossiers_id.include?(dossier.id) }
- else
%h2 Aucun dossier correspondant à votre recherche n'a été trouvé

View file

@ -5,8 +5,8 @@ describe DossierProjectionService do
context 'with multiple dossier' do
let!(:procedure) { create(:procedure, :with_type_de_champ) }
let!(:dossier_1) { create(:dossier, procedure: procedure) }
let!(:dossier_2) { create(:dossier, procedure: procedure) }
let!(:dossier_3) { create(:dossier, procedure: procedure) }
let!(:dossier_2) { create(:dossier, :en_construction, :archived, procedure: procedure) }
let!(:dossier_3) { create(:dossier, :en_instruction, procedure: procedure) }
let(:dossiers_ids) { [dossier_3.id, dossier_1.id, dossier_2.id] }
let(:fields) do
@ -26,11 +26,20 @@ describe DossierProjectionService do
let(:result) { subject }
it 'respects the dossiers_ids order and returns nil for empty result' do
it 'respects the dossiers_ids order, returns state, archived and nil for empty result' do
expect(result.length).to eq(3)
expect(result[0].dossier.id).to eq(dossier_3.id)
expect(result[1].dossier.id).to eq(dossier_1.id)
expect(result[2].dossier.id).to eq(dossier_2.id)
expect(result[0].dossier_id).to eq(dossier_3.id)
expect(result[1].dossier_id).to eq(dossier_1.id)
expect(result[2].dossier_id).to eq(dossier_2.id)
expect(result[0].state).to eq('en_instruction')
expect(result[1].state).to eq('brouillon')
expect(result[2].state).to eq('en_construction')
expect(result[0].archived).to be false
expect(result[1].archived).to be false
expect(result[2].archived).to be true
expect(result[0].columns[0]).to be nil
expect(result[1].columns[0]).to eq('champ_1')