diff --git a/app/services/dossier_projection_service.rb b/app/services/dossier_projection_service.rb index a53905cec..670f021e7 100644 --- a/app/services/dossier_projection_service.rb +++ b/app/services/dossier_projection_service.rb @@ -18,57 +18,53 @@ 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) - champ_fields, other_fields = fields - .partition { |f| ['type_de_champ', 'type_de_champ_private'].include?(f[TABLE]) } - - if champ_fields.present? - Champ - .includes(:type_de_champ) - .where( - # as querying the champs table is costly - # we fetch all the requested champs at once - types_de_champ: { stable_id: champ_fields.map { |f| f[COLUMN] } }, - dossier_id: dossiers_ids - ) - .select(:dossier_id, :value, :type_de_champ_id, :stable_id) # we cannot pluck :value, as we need the champ.to_s method - .group_by(&:stable_id) # the champs are redispatched to their respective fields - .map do |stable_id, champs| - field = champ_fields.find { |f| f[COLUMN] == stable_id.to_s } - field[:id_value_h] = champs.to_h { |c| [c.dossier_id, c.to_s] } - end - end - - other_fields.each do |field| - field[:id_value_h] = case field[TABLE] + fields + .each { |f| f[:id_value_h] = {} } + .group_by { |f| f[TABLE] } # one query per table + .each do |table, fields| + case table + when 'type_de_champ', 'type_de_champ_private' + Champ + .includes(:type_de_champ) + .where( + types_de_champ: { stable_id: fields.map { |f| f[COLUMN] } }, + dossier_id: dossiers_ids + ) + .select(:dossier_id, :value, :type_de_champ_id, :stable_id) # we cannot pluck :value, as we need the champ.to_s method + .group_by(&:stable_id) # the champs are redispatched to their respective fields + .map do |stable_id, champs| + field = fields.find { |f| f[COLUMN] == stable_id.to_s } + field[:id_value_h] = champs.to_h { |c| [c.dossier_id, c.to_s] } + end when 'self' Dossier .where(id: dossiers_ids) - .pluck(:id, field[COLUMN].to_sym) - .to_h { |id, col| [id, col&.strftime('%d/%m/%Y')] } + .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') } } + when 'individual' + Individual + .where(dossier_id: dossiers_ids) + .pluck(:dossier_id, *fields.map { |f| f[COLUMN].to_sym }) + .each { |id, *columns| fields.zip(columns).each { |field, value| field[:id_value_h][id] = value } } + when 'etablissement' + Etablissement + .where(dossier_id: dossiers_ids) + .pluck(:dossier_id, *fields.map { |f| f[COLUMN].to_sym }) + .each { |id, *columns| fields.zip(columns).each { |field, value| field[:id_value_h][id] = value } } when 'user' - Dossier + fields[0][:id_value_h] = Dossier # there is only one field available for user table .joins(:user) .where(id: dossiers_ids) .pluck('dossiers.id, users.email') .to_h - when 'individual' - Individual - .where(dossier_id: dossiers_ids) - .pluck(:dossier_id, field[COLUMN].to_sym) - .to_h - when 'etablissement' - Etablissement - .where(dossier_id: dossiers_ids) - .pluck(:dossier_id, field[COLUMN].to_sym) - .to_h when 'groupe_instructeur' - Dossier + fields[0][:id_value_h] = Dossier .joins(:groupe_instructeur) .where(id: dossiers_ids) .pluck('dossiers.id, groupe_instructeurs.label') .to_h when 'followers_instructeurs' - Follow + fields[0][:id_value_h] = Follow .active .joins(instructeur: :user) .where(dossier_id: dossiers_ids)