Merge pull request #4772 from tchak/discard

Use discard gem instead of DIY solution
This commit is contained in:
Paul Chavard 2020-02-13 16:51:05 +01:00 committed by GitHub
commit 67867d7cff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 44 additions and 72 deletions

View file

@ -23,6 +23,7 @@ gem 'delayed_job_active_record'
gem 'delayed_job_web' gem 'delayed_job_web'
gem 'devise' # Gestion des comptes utilisateurs gem 'devise' # Gestion des comptes utilisateurs
gem 'devise-async' gem 'devise-async'
gem 'discard'
gem 'dotenv-rails', require: 'dotenv/rails-now' # dotenv should always be loaded before rails gem 'dotenv-rails', require: 'dotenv/rails-now' # dotenv should always be loaded before rails
gem 'flipper' gem 'flipper'
gem 'flipper-active_record' gem 'flipper-active_record'

View file

@ -187,6 +187,8 @@ GEM
activejob (>= 5.0) activejob (>= 5.0)
devise (>= 4.0) devise (>= 4.0)
diff-lcs (1.3) diff-lcs (1.3)
discard (1.1.0)
activerecord (>= 4.2, < 7)
domain_name (0.5.20180417) domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.5.0) dotenv (2.5.0)
@ -737,6 +739,7 @@ DEPENDENCIES
delayed_job_web delayed_job_web
devise devise
devise-async devise-async
discard
dotenv-rails dotenv-rails
factory_bot factory_bot
flipper flipper

View file

@ -9,10 +9,10 @@ module Manager
def scoped_resource def scoped_resource
if unfiltered_list? if unfiltered_list?
# Don't display deleted dossiers in the unfiltered list… # Don't display deleted dossiers in the unfiltered list…
Procedure Procedure.kept
else else
# … but allow them to be searched and displayed. # … but allow them to be searched and displayed.
Procedure.with_hidden Procedure.with_discarded
end end
end end

View file

@ -2,6 +2,10 @@ class Dossier < ApplicationRecord
self.ignored_columns = ['json_latlngs'] self.ignored_columns = ['json_latlngs']
include DossierFilteringConcern include DossierFilteringConcern
include Discard::Model
self.discard_column = :hidden_at
default_scope -> { kept }
enum state: { enum state: {
brouillon: 'brouillon', brouillon: 'brouillon',
en_construction: 'en_construction', en_construction: 'en_construction',
@ -94,9 +98,6 @@ class Dossier < ApplicationRecord
end end
end end
default_scope { where(hidden_at: nil) }
scope :hidden, -> { unscope(where: :hidden_at).where.not(hidden_at: nil) }
scope :with_hidden, -> { unscope(where: :hidden_at) }
scope :state_brouillon, -> { where(state: states.fetch(:brouillon)) } scope :state_brouillon, -> { where(state: states.fetch(:brouillon)) }
scope :state_not_brouillon, -> { where.not(state: states.fetch(:brouillon)) } scope :state_not_brouillon, -> { where.not(state: states.fetch(:brouillon)) }
scope :state_en_construction, -> { where(state: states.fetch(:en_construction)) } scope :state_en_construction, -> { where(state: states.fetch(:en_construction)) }
@ -378,7 +379,7 @@ class Dossier < ApplicationRecord
def delete_and_keep_track(author) def delete_and_keep_track(author)
deleted_dossier = DeletedDossier.create_from_dossier(self) deleted_dossier = DeletedDossier.create_from_dossier(self)
update(hidden_at: deleted_dossier.deleted_at) discard!
if en_construction? if en_construction?
administration_emails = followers_instructeurs.present? ? followers_instructeurs.map(&:email) : procedure.administrateurs.map(&:email) administration_emails = followers_instructeurs.present? ? followers_instructeurs.map(&:email) : procedure.administrateurs.map(&:email)

View file

@ -16,5 +16,7 @@ class Invite < ApplicationRecord
# and Dossier from their respective `default_scope`s. # and Dossier from their respective `default_scope`s.
# Therefore, we also remove `Invite`s for such effectively deleted `Dossier`s # Therefore, we also remove `Invite`s for such effectively deleted `Dossier`s
# from their default scope. # from their default scope.
default_scope { joins(:dossier).where(dossiers: { hidden_at: nil }) } scope :kept, -> { joins(:dossier).merge(Dossier.kept) }
default_scope { kept }
end end

View file

@ -5,6 +5,10 @@ class Procedure < ApplicationRecord
include ProcedureStatsConcern include ProcedureStatsConcern
include Discard::Model
self.discard_column = :hidden_at
default_scope -> { kept }
MAX_DUREE_CONSERVATION = 36 MAX_DUREE_CONSERVATION = 36
MAX_DUREE_CONSERVATION_EXPORT = 3.hours MAX_DUREE_CONSERVATION_EXPORT = 3.hours
@ -44,9 +48,6 @@ class Procedure < ApplicationRecord
accepts_nested_attributes_for :types_de_champ, reject_if: proc { |attributes| attributes['libelle'].blank? }, allow_destroy: true accepts_nested_attributes_for :types_de_champ, reject_if: proc { |attributes| attributes['libelle'].blank? }, allow_destroy: true
accepts_nested_attributes_for :types_de_champ_private, reject_if: proc { |attributes| attributes['libelle'].blank? }, allow_destroy: true accepts_nested_attributes_for :types_de_champ_private, reject_if: proc { |attributes| attributes['libelle'].blank? }, allow_destroy: true
default_scope { where(hidden_at: nil) }
scope :hidden, -> { unscope(where: :hidden_at).where.not(hidden_at: nil) }
scope :with_hidden, -> { unscope(where: :hidden_at) }
scope :brouillons, -> { where(aasm_state: :brouillon) } scope :brouillons, -> { where(aasm_state: :brouillon) }
scope :publiees, -> { where(aasm_state: :publiee) } scope :publiees, -> { where(aasm_state: :publiee) }
scope :closes, -> { where(aasm_state: [:close, :depubliee]) } scope :closes, -> { where(aasm_state: [:close, :depubliee]) }
@ -99,7 +100,6 @@ class Procedure < ApplicationRecord
state :brouillon, initial: true state :brouillon, initial: true
state :publiee state :publiee
state :close state :close
state :hidden
state :depubliee state :depubliee
event :publish, before: :before_publish, after: :after_publish do event :publish, before: :before_publish, after: :after_publish do
@ -112,12 +112,6 @@ class Procedure < ApplicationRecord
transitions from: :publiee, to: :close transitions from: :publiee, to: :close
end end
event :hide, after: :after_hide do
transitions from: :brouillon, to: :hidden
transitions from: :publiee, to: :hidden
transitions from: :close, to: :hidden
end
event :unpublish, after: :after_unpublish do event :unpublish, after: :after_unpublish do
transitions from: :publiee, to: :depubliee transitions from: :publiee, to: :depubliee
end end
@ -597,6 +591,12 @@ class Procedure < ApplicationRecord
groupe_instructeurs.count > 1 groupe_instructeurs.count > 1
end end
def hide!
discard!
dossiers.discard_all
purge_export_files
end
private private
def move_type_de_champ_attributes(types_de_champ, type_de_champ, new_index) def move_type_de_champ_attributes(types_de_champ, type_de_champ, new_index)
@ -629,13 +629,6 @@ class Procedure < ApplicationRecord
purge_export_files purge_export_files
end end
def after_hide
now = Time.zone.now
update!(hidden_at: now)
dossiers.update_all(hidden_at: now)
purge_export_files
end
def after_unpublish def after_unpublish
update!(unpublished_at: Time.zone.now) update!(unpublished_at: Time.zone.now)
end end

View file

@ -108,7 +108,7 @@ class User < ApplicationRecord
dossiers.each do |dossier| dossiers.each do |dossier|
dossier.delete_and_keep_track(administration) dossier.delete_and_keep_track(administration)
end end
dossiers.with_hidden.destroy_all dossiers.with_discarded.destroy_all
destroy! destroy!
end end

View file

@ -39,7 +39,7 @@ as well as a link to its edit page.
<%= link_to 'whitelister', whitelist_manager_procedure_path(procedure), method: :post, class: 'button' %> <%= link_to 'whitelister', whitelist_manager_procedure_path(procedure), method: :post, class: 'button' %>
<% end %> <% end %>
<% if !procedure.hidden? %> <% if !procedure.discarded? %>
<%= link_to 'supprimer la démarche', hide_manager_procedure_path(procedure), method: :post, class: 'button', data: { confirm: "Confirmez-vous la suppression de la démarche ?" } %> <%= link_to 'supprimer la démarche', hide_manager_procedure_path(procedure), method: :post, class: 'button', data: { confirm: "Confirmez-vous la suppression de la démarche ?" } %>
<% end %> <% end %>
<div> <div>

View file

@ -4,7 +4,7 @@ namespace :fix_timestamps_of_migrated_dossiers do
desc 'Fix the timestamps of dossiers affected by the faulty PJ migration' desc 'Fix the timestamps of dossiers affected by the faulty PJ migration'
task run: :environment do task run: :environment do
affected_time_range = Time.utc(2019, 6, 4, 8, 0)..Time.utc(2019, 6, 4, 18, 0) affected_time_range = Time.utc(2019, 6, 4, 8, 0)..Time.utc(2019, 6, 4, 18, 0)
dossiers = Dossier.with_hidden.includes(:groupe_instructeur).where(groupe_instructeurs: { procedure_id: 0..1000 }).where(updated_at: affected_time_range) dossiers = Dossier.with_discarded.includes(:groupe_instructeur).where(groupe_instructeurs: { procedure_id: 0..1000 }).where(updated_at: affected_time_range)
progress = ProgressReport.new(dossiers.count) progress = ProgressReport.new(dossiers.count)

View file

@ -3,7 +3,7 @@ namespace :after_party do
task create_dummy_paths_for_archived_and_hidden_procedures: :environment do task create_dummy_paths_for_archived_and_hidden_procedures: :environment do
rake_puts "Running deploy task 'create_dummy_paths_for_archived_procedures'" rake_puts "Running deploy task 'create_dummy_paths_for_archived_procedures'"
Procedure.with_hidden.archivees.where(path: nil).each do |p| Procedure.with_discarded.archivees.where(path: nil).each do |p|
p.update_column(:path, SecureRandom.uuid) p.update_column(:path, SecureRandom.uuid)
end end

View file

@ -2,7 +2,7 @@ namespace :after_party do
desc 'Deployment task: create_default_groupe_instructeur' desc 'Deployment task: create_default_groupe_instructeur'
task create_default_groupe_instructeur: :environment do task create_default_groupe_instructeur: :environment do
Procedure Procedure
.with_hidden .with_discarded
.left_outer_joins(:groupe_instructeurs) .left_outer_joins(:groupe_instructeurs)
.where('groupe_instructeurs.id is null') .where('groupe_instructeurs.id is null')
.find_each do |procedure| .find_each do |procedure|

View file

@ -61,7 +61,7 @@ FactoryBot.define do
archived { false } archived { false }
end end
trait :hidden do trait :discarded do
hidden_at { Time.zone.now } hidden_at { Time.zone.now }
end end

View file

@ -185,7 +185,7 @@ FactoryBot.define do
end end
end end
trait :hidden do trait :discarded do
after(:build) do |procedure, _evaluator| after(:build) do |procedure, _evaluator|
procedure.path = generate(:published_path) procedure.path = generate(:published_path)
procedure.publish! procedure.publish!

View file

@ -46,8 +46,8 @@ RSpec.describe FindDubiousProceduresJob, type: :job do
it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) } it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) }
end end
context 'and a hidden procedure' do context 'and a discarded procedure' do
let(:procedure) { create(:procedure, :hidden) } let(:procedure) { create(:procedure, :discarded) }
it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) } it { expect(AdministrationMailer).to have_received(:dubious_procedures).with([]) }
end end

View file

@ -18,17 +18,17 @@ describe '20190819142551_create_default_groupe_instructeur.rake' do
end end
end end
context 'with a procedure hidden without gi' do context 'with a procedure discarded without gi' do
let!(:procedure_hidden_without_gi) { create(:procedure, :hidden) } let!(:procedure_discarded_without_gi) { create(:procedure, :discarded) }
before do before do
procedure_hidden_without_gi.groupe_instructeurs.destroy_all procedure_discarded_without_gi.groupe_instructeurs.destroy_all
end end
it do it do
expect(procedure_hidden_without_gi.groupe_instructeurs).to be_empty expect(procedure_discarded_without_gi.groupe_instructeurs).to be_empty
subject subject
expect(procedure_hidden_without_gi.reload.groupe_instructeurs.pluck(:label)).to eq(['défaut']) expect(procedure_discarded_without_gi.reload.groupe_instructeurs.pluck(:label)).to eq(['défaut'])
end end
end end

View file

@ -8,31 +8,13 @@ describe Dossier do
describe 'scopes' do describe 'scopes' do
describe '.default_scope' do describe '.default_scope' do
let!(:dossier) { create(:dossier) } let!(:dossier) { create(:dossier) }
let!(:hidden_dossier) { create(:dossier, :hidden) } let!(:discarded_dossier) { create(:dossier, :discarded) }
subject { Dossier.all } subject { Dossier.all }
it { is_expected.to match_array([dossier]) } it { is_expected.to match_array([dossier]) }
end end
describe '.hidden' do
let!(:dossier) { create(:dossier) }
let!(:hidden_dossier) { create(:dossier, :hidden) }
subject { Dossier.all.hidden }
it { is_expected.to match_array([hidden_dossier]) }
end
describe '.with_hidden' do
let!(:dossier) { create(:dossier) }
let!(:hidden_dossier) { create(:dossier, :hidden) }
subject { Dossier.all.with_hidden }
it { is_expected.to match_array([dossier, hidden_dossier]) }
end
describe '.without_followers' do describe '.without_followers' do
let!(:dossier_with_follower) { create(:dossier, :followed, :with_entreprise, user: user) } let!(:dossier_with_follower) { create(:dossier, :followed, :with_entreprise, user: user) }
let!(:dossier_without_follower) { create(:dossier, :with_entreprise, user: user) } let!(:dossier_without_follower) { create(:dossier, :with_entreprise, user: user) }

View file

@ -61,14 +61,14 @@ describe Invite do
let(:dossier) { create(:dossier, hidden_at: hidden_at) } let(:dossier) { create(:dossier, hidden_at: hidden_at) }
let!(:invite) { create(:invite, email: "email@totor.com", dossier: dossier) } let!(:invite) { create(:invite, email: "email@totor.com", dossier: dossier) }
context "when dossier is not hidden" do context "when dossier is not discarded" do
let(:hidden_at) { nil } let(:hidden_at) { nil }
it { expect(Invite.count).to eq(1) } it { expect(Invite.count).to eq(1) }
it { expect(Invite.all).to include(invite) } it { expect(Invite.all).to include(invite) }
end end
context "when dossier is hidden" do context "when dossier is discarded" do
let(:hidden_at) { 1.day.ago } let(:hidden_at) { 1.day.ago }
it { expect(Invite.count).to eq(0) } it { expect(Invite.count).to eq(0) }

View file

@ -153,22 +153,12 @@ describe Procedure do
describe 'scopes' do describe 'scopes' do
let!(:procedure) { create(:procedure) } let!(:procedure) { create(:procedure) }
let!(:hidden_procedure) { create(:procedure, :hidden) } let!(:discarded_procedure) { create(:procedure, :discarded) }
describe 'default_scope' do describe 'default_scope' do
subject { Procedure.all } subject { Procedure.all }
it { is_expected.to match_array([procedure]) } it { is_expected.to match_array([procedure]) }
end end
describe '.hidden' do
subject { Procedure.all.hidden }
it { is_expected.to match_array([hidden_procedure]) }
end
describe '.with_hidden' do
subject { Procedure.all.with_hidden }
it { is_expected.to match_array([procedure, hidden_procedure]) }
end
end end
describe 'validation' do describe 'validation' do

View file

@ -259,7 +259,7 @@ describe User, type: :model do
let!(:dossier_en_construction) { create(:dossier, :en_construction, user: user) } let!(:dossier_en_construction) { create(:dossier, :en_construction, user: user) }
let!(:dossier_brouillon) { create(:dossier, user: user) } let!(:dossier_brouillon) { create(:dossier, user: user) }
context 'without a hidden dossier' do context 'without a discarded dossier' do
it "keep track of dossiers and delete user" do it "keep track of dossiers and delete user" do
user.delete_and_keep_track_dossiers(administration) user.delete_and_keep_track_dossiers(administration)
@ -269,7 +269,7 @@ describe User, type: :model do
end end
end end
context 'with a hidden dossier' do context 'with a discarded dossier' do
let!(:dossier_cache) do let!(:dossier_cache) do
create(:dossier, :en_construction, user: user) create(:dossier, :en_construction, user: user)
end end