1
app/assets/images/agentconnect-btn-principal-hover.svg
Normal file
After Width: | Height: | Size: 19 KiB |
1
app/assets/images/agentconnect-btn-principal.svg
Normal file
After Width: | Height: | Size: 19 KiB |
1
app/assets/images/franceconnect-btn-hover.svg
Normal file
After Width: | Height: | Size: 19 KiB |
1
app/assets/images/franceconnect-btn.svg
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 3.5 KiB |
|
@ -18,7 +18,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.column {
|
.column {
|
||||||
padding-top: 2 * $default-spacer;
|
padding-top: $default-spacer;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-bottom: $default-spacer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form label {
|
||||||
|
margin-bottom: $default-spacer / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +34,7 @@
|
||||||
.auth-options {
|
.auth-options {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-bottom: 4 * $default-spacer;
|
margin-bottom: 2 * $default-spacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.remember-me {
|
.remember-me {
|
||||||
|
@ -60,7 +68,7 @@
|
||||||
|
|
||||||
.sign-in-form .form {
|
.sign-in-form .form {
|
||||||
input[type="email"] {
|
input[type="email"] {
|
||||||
margin-bottom: $default-padding;
|
margin-bottom: $default-spacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="password"] {
|
input[type="password"] {
|
||||||
|
|
|
@ -2,10 +2,14 @@
|
||||||
@import "constants";
|
@import "constants";
|
||||||
|
|
||||||
.france-connect-agent-login-button {
|
.france-connect-agent-login-button {
|
||||||
background-image: image-url("logo-agent-connect.png");
|
background-image: image-url("agentconnect-btn-principal.svg"), image-url("agentconnect-btn-principal-hover.svg");
|
||||||
display: block;
|
display: block;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
width: 230px;
|
width: 206px;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-image: image-url("agentconnect-btn-principal-hover.svg");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,14 @@
|
||||||
width: 230px;
|
width: 230px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
background-image: image-url("login-with-fc.svg"), image-url("login-with-fc-hover.svg");
|
background-image: image-url("franceconnect-btn.svg"), image-url("franceconnect-btn-hover.svg");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-image: image-url("login-with-fc-hover.svg");
|
background-image: image-url("franceconnect-btn-hover.svg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: $black;
|
color: $black;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
padding-bottom: $default-padding;
|
padding-bottom: $default-spacer;
|
||||||
padding-top: $default-padding;
|
padding-top: $default-spacer;
|
||||||
|
|
||||||
&::before,
|
&::before,
|
||||||
&::after {
|
&::after {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Some of this file is lifted from Gitlab's `lib/gitlab/database/migration_helpers.rb``
|
# Some of this file is lifted from Gitlab's `lib/gitlab/database/migration_helpers.rb`
|
||||||
|
|
||||||
# Copyright (c) 2011-present GitLab B.V.
|
# Copyright (c) 2011-present GitLab B.V.
|
||||||
#
|
#
|
||||||
|
@ -103,6 +103,34 @@ module Database::MigrationHelpers
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Delete records from `from_table` having a reference to a missing record in `to_table`.
|
||||||
|
# This is useful to rectify data before adding a proper foreign_key.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# delete_orphans :appointments, :physicians
|
||||||
|
#
|
||||||
|
def delete_orphans(from_table, to_table)
|
||||||
|
say_with_time "Deleting records from #{from_table} where the associated #{to_table.to_s.singularize} no longer exists" do
|
||||||
|
from_table = Arel::Table.new(from_table)
|
||||||
|
to_table = Arel::Table.new(to_table)
|
||||||
|
foreign_key_column = foreign_key_column_for(to_table.name)
|
||||||
|
|
||||||
|
# Select the ids of orphan records
|
||||||
|
arel_select = from_table
|
||||||
|
.join(to_table, Arel::Nodes::OuterJoin).on(to_table[:id].eq(from_table[foreign_key_column]))
|
||||||
|
.where(to_table[:id].eq(nil))
|
||||||
|
.project(from_table[foreign_key_column])
|
||||||
|
missing_record_ids = query_values(arel_select.to_sql)
|
||||||
|
|
||||||
|
# Delete the records having ids referencing missing data
|
||||||
|
arel_delete = Arel::DeleteManager.new()
|
||||||
|
.from(from_table)
|
||||||
|
.where(from_table[foreign_key_column].in(missing_record_ids.uniq))
|
||||||
|
exec_delete(arel_delete.to_sql)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def statement_timeout_disabled?
|
def statement_timeout_disabled?
|
||||||
|
|
|
@ -176,7 +176,7 @@ class Procedure < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
has_many :administrateurs_procedures
|
has_many :administrateurs_procedures, dependent: :delete_all
|
||||||
has_many :administrateurs, through: :administrateurs_procedures, after_remove: -> (procedure, _admin) { procedure.validate! }
|
has_many :administrateurs, through: :administrateurs_procedures, after_remove: -> (procedure, _admin) { procedure.validate! }
|
||||||
has_many :groupe_instructeurs, dependent: :destroy
|
has_many :groupe_instructeurs, dependent: :destroy
|
||||||
has_many :instructeurs, through: :groupe_instructeurs
|
has_many :instructeurs, through: :groupe_instructeurs
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
= f.label :message_on_submit_by_usager do
|
= f.label :message_on_submit_by_usager do
|
||||||
Message affiché après l'envoie du dossier
|
Message affiché après l'envoi du dossier
|
||||||
= f.text_area :message_on_submit_by_usager, placeholder: "Merci votre dossier sera traité dans les plus bref delais"
|
= f.text_area :message_on_submit_by_usager, placeholder: "Merci, votre dossier sera traité dans les plus bref delais"
|
||||||
|
|
|
@ -246,6 +246,6 @@
|
||||||
%p.card-admin-status-todo À configurer
|
%p.card-admin-status-todo À configurer
|
||||||
%div
|
%div
|
||||||
%p.card-admin-title Fin de dépot
|
%p.card-admin-title Fin de dépot
|
||||||
%p.card-admin-subtitle Orienter l'usager suite à l'envoie de son dossier
|
%p.card-admin-subtitle Orienter l'usager suite à l'envoi de son dossier
|
||||||
%p.button Modifier
|
%p.button Modifier
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,5 @@
|
||||||
.france-connect-login-separator
|
.france-connect-login-separator
|
||||||
= t('views.shared.france_connect_login.separator')
|
= t('views.shared.france_connect_login.separator')
|
||||||
.center
|
.center
|
||||||
%h2.important-header= t('views.users.sessions.new.state_civil_servant')
|
%h2.important-header.mb-1= t('views.users.sessions.new.state_civil_servant')
|
||||||
%br
|
|
||||||
= link_to t('views.users.sessions.new.connect_with_agent_connect'), agent_connect_path, class: "button expend secondary"
|
= link_to t('views.users.sessions.new.connect_with_agent_connect'), agent_connect_path, class: "button expend secondary"
|
||||||
|
|
|
@ -11,7 +11,7 @@ en:
|
||||||
The ministries and operators that can currently benefit from it are :
|
The ministries and operators that can currently benefit from it are :
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>the Ministry of Ecological Transition</li>
|
<li>the Insee</li>
|
||||||
</ul>
|
</ul>
|
||||||
you_are_a_citizen: You are an individual ?
|
you_are_a_citizen: You are an individual ?
|
||||||
citizen_page: Go to our dedicated page
|
citizen_page: Go to our dedicated page
|
||||||
|
|
|
@ -8,10 +8,10 @@ fr:
|
||||||
<p>
|
<p>
|
||||||
<b class="bold">AgentConnect est en cours de déploiement.</b>
|
<b class="bold">AgentConnect est en cours de déploiement.</b>
|
||||||
<br>
|
<br>
|
||||||
Les ministères et opérateurs qui peuvent l'utiliser à ce jour sont :
|
Les ministères et opérateurs qui peuvent lʼutiliser à ce jour sont :
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>le ministère de la Transition écologique</li>
|
<li>lʼInsee</li>
|
||||||
</ul>
|
</ul>
|
||||||
you_are_a_citizen: Vous êtes un particulier ?
|
you_are_a_citizen: Vous êtes un particulier ?
|
||||||
citizen_page: Accéder à notre page dédiée
|
citizen_page: Accéder à notre page dédiée
|
||||||
|
|
|
@ -11,7 +11,7 @@ en:
|
||||||
en_attente: "Waiting for response"
|
en_attente: "Waiting for response"
|
||||||
france_connect_login:
|
france_connect_login:
|
||||||
title: "With FranceConnect"
|
title: "With FranceConnect"
|
||||||
description: "France connect is a solution proposed by the government to secure and simplify the connection to web services."
|
description: "FranceConnect is a solution proposed by the government to secure and simplify the connection to web services."
|
||||||
login_button: "Sign in with FranceConnect"
|
login_button: "Sign in with FranceConnect"
|
||||||
help_link: What is FranceConnect?
|
help_link: What is FranceConnect?
|
||||||
separator: or
|
separator: or
|
||||||
|
|
|
@ -11,7 +11,7 @@ fr:
|
||||||
en_attente: "En attente de réponse"
|
en_attente: "En attente de réponse"
|
||||||
france_connect_login:
|
france_connect_login:
|
||||||
title: 'Avec FranceConnect'
|
title: 'Avec FranceConnect'
|
||||||
description: "France connect est la solution proposée par l’État pour sécuriser et simplifier la connexion aux services en ligne."
|
description: "FranceConnect est la solution proposée par l’État pour sécuriser et simplifier la connexion aux services en ligne."
|
||||||
login_button: "S’identifier avec FranceConnect"
|
login_button: "S’identifier avec FranceConnect"
|
||||||
help_link: "Qu’est-ce que FranceConnect ?"
|
help_link: "Qu’est-ce que FranceConnect ?"
|
||||||
separator: 'ou'
|
separator: 'ou'
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
class AddAdministrateurForeignKeyToAdministrateursProcedure < ActiveRecord::Migration[6.1]
|
class AddAdministrateurForeignKeyToAdministrateursProcedure < ActiveRecord::Migration[6.1]
|
||||||
def up
|
include Database::MigrationHelpers
|
||||||
# Sanity check
|
|
||||||
say_with_time 'Removing AdministrateursProcedures where the associated Administrateur no longer exists ' do
|
|
||||||
deleted_administrateur_ids = AdministrateursProcedure.where.missing(:administrateur).pluck(:administrateur_id)
|
|
||||||
AdministrateursProcedure.where(administrateur_id: deleted_administrateur_ids).delete_all
|
|
||||||
end
|
|
||||||
|
|
||||||
add_foreign_key :administrateurs_procedures, :administrateurs
|
def up
|
||||||
|
delete_orphans :administrateurs_procedures, :administrateurs_procedures
|
||||||
|
add_foreign_key :administrateurs_procedures, :administrateurs_procedures
|
||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
class AddForeignKeysToAdministrateursInstructeurs < ActiveRecord::Migration[6.1]
|
class AddForeignKeysToAdministrateursInstructeurs < ActiveRecord::Migration[6.1]
|
||||||
|
include Database::MigrationHelpers
|
||||||
|
|
||||||
def up
|
def up
|
||||||
# Sanity check
|
delete_orphans :administrateurs_instructeurs, :administrateurs
|
||||||
say_with_time 'Removing AdministrateursInstructeur where the associated Administrateur no longer exists ' do
|
|
||||||
deleted_administrateurs_ids = AdministrateursInstructeur.where.missing(:administrateur).pluck(:administrateur_id)
|
|
||||||
AdministrateursInstructeur.where(administrateur_id: deleted_administrateurs_ids).delete_all
|
|
||||||
end
|
|
||||||
|
|
||||||
say_with_time 'Removing AdministrateursInstructeur where the associated Instructeur no longer exists ' do
|
|
||||||
deleted_instructeurs_ids = AdministrateursInstructeur.where.missing(:instructeur).pluck(:instructeur_id)
|
|
||||||
AdministrateursInstructeur.where(instructeur_id: deleted_instructeurs_ids).delete_all
|
|
||||||
end
|
|
||||||
|
|
||||||
add_foreign_key :administrateurs_instructeurs, :administrateurs
|
add_foreign_key :administrateurs_instructeurs, :administrateurs
|
||||||
|
|
||||||
|
delete_orphans :administrateurs_instructeurs, :instructeurs
|
||||||
add_foreign_key :administrateurs_instructeurs, :instructeurs
|
add_foreign_key :administrateurs_instructeurs, :instructeurs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
class AddProcedureForeignKeyToAdministrateursProcedure < ActiveRecord::Migration[6.1]
|
||||||
|
include Database::MigrationHelpers
|
||||||
|
|
||||||
|
def up
|
||||||
|
delete_orphans :administrateurs_procedures, :procedures
|
||||||
|
add_foreign_key :administrateurs_procedures, :procedures
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_foreign_key :administrateurs_procedures, :procedures
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2022_03_02_101337) do
|
ActiveRecord::Schema.define(version: 2022_03_08_110720) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -855,6 +855,7 @@ ActiveRecord::Schema.define(version: 2022_03_02_101337) do
|
||||||
add_foreign_key "administrateurs_instructeurs", "administrateurs"
|
add_foreign_key "administrateurs_instructeurs", "administrateurs"
|
||||||
add_foreign_key "administrateurs_instructeurs", "instructeurs"
|
add_foreign_key "administrateurs_instructeurs", "instructeurs"
|
||||||
add_foreign_key "administrateurs_procedures", "administrateurs"
|
add_foreign_key "administrateurs_procedures", "administrateurs"
|
||||||
|
add_foreign_key "administrateurs_procedures", "procedures"
|
||||||
add_foreign_key "archives_groupe_instructeurs", "archives"
|
add_foreign_key "archives_groupe_instructeurs", "archives"
|
||||||
add_foreign_key "archives_groupe_instructeurs", "groupe_instructeurs"
|
add_foreign_key "archives_groupe_instructeurs", "groupe_instructeurs"
|
||||||
add_foreign_key "assign_tos", "groupe_instructeurs"
|
add_foreign_key "assign_tos", "groupe_instructeurs"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
describe Database::MigrationHelpers do
|
describe Database::MigrationHelpers do
|
||||||
|
describe 'handling duplicates' do
|
||||||
class TestLabel < ApplicationRecord
|
class TestLabel < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -8,6 +9,10 @@ describe Database::MigrationHelpers do
|
||||||
t.string :label
|
t.string :label
|
||||||
t.integer :user_id
|
t.integer :user_id
|
||||||
end
|
end
|
||||||
|
ActiveRecord::Migration.create_table "test_labels", force: true do |t|
|
||||||
|
t.string :label
|
||||||
|
t.integer :user_id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -87,6 +92,105 @@ describe Database::MigrationHelpers do
|
||||||
expect(TestLabel.where(label: 'Done').count).to eq(1)
|
expect(TestLabel.where(label: 'Done').count).to eq(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.delete_orphans' do
|
||||||
|
class TestPhysician < ApplicationRecord; end
|
||||||
|
|
||||||
|
class TestPatient < ApplicationRecord; end
|
||||||
|
|
||||||
|
class TestAppointment < ApplicationRecord; end
|
||||||
|
|
||||||
|
before(:all) do
|
||||||
|
ActiveRecord::Migration.suppress_messages do
|
||||||
|
ActiveRecord::Migration.create_table "test_physicians", force: true do |t|
|
||||||
|
t.string :name
|
||||||
|
end
|
||||||
|
ActiveRecord::Migration.create_table "test_patients", force: true do |t|
|
||||||
|
t.string :name
|
||||||
|
end
|
||||||
|
ActiveRecord::Migration.create_table "test_appointments", id: false, force: true do |t|
|
||||||
|
t.integer :test_physician_id
|
||||||
|
t.integer :test_patient_id
|
||||||
|
t.datetime :datetime
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:all) do
|
||||||
|
ActiveRecord::Migration.suppress_messages do
|
||||||
|
ActiveRecord::Migration.drop_table :test_physicians, force: true
|
||||||
|
ActiveRecord::Migration.drop_table :test_patients, force: true
|
||||||
|
ActiveRecord::Migration.drop_table :test_appointments, force: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:model) { ActiveRecord::Migration.new.extend(Database::MigrationHelpers) }
|
||||||
|
|
||||||
|
subject do
|
||||||
|
model.delete_orphans(:test_appointments, :test_patients)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there are orphan records' do
|
||||||
|
before(:each) do
|
||||||
|
phy1 = TestPhysician.create({ name: 'Ibn Sina' })
|
||||||
|
phy2 = TestPhysician.create({ name: 'Louis Pasteur' })
|
||||||
|
pa1 = TestPatient.create({ name: 'Chams ad-Dawla' })
|
||||||
|
pa2 = TestPatient.create({ name: 'Joseph Meister' })
|
||||||
|
ap1 = TestAppointment.create({ test_physician_id: phy1.id, test_patient_id: pa1.id, datetime: 2.months.ago })
|
||||||
|
ap2 = TestAppointment.create({ test_physician_id: phy1.id, test_patient_id: pa1.id, datetime: 1.month.ago })
|
||||||
|
ap3 = TestAppointment.create({ test_physician_id: phy2.id, test_patient_id: pa2.id, datetime: 2.days.ago })
|
||||||
|
ap4 = TestAppointment.create({ test_physician_id: phy1.id, test_patient_id: pa2.id, datetime: 1.day.ago })
|
||||||
|
ap5 = TestAppointment.create({ test_physician_id: phy1.id, test_patient_id: pa1.id, datetime: Time.zone.today })
|
||||||
|
|
||||||
|
# Appointments missing the associated patient
|
||||||
|
ap6 = TestAppointment.create({ test_physician_id: phy1.id, test_patient_id: 9999, datetime: 3.months.ago })
|
||||||
|
ap7 = TestAppointment.create({ test_physician_id: phy1.id, test_patient_id: 8888, datetime: 2.months.ago })
|
||||||
|
ap8 = TestAppointment.create({ test_physician_id: phy2.id, test_patient_id: 8888, datetime: 1.month.ago })
|
||||||
|
|
||||||
|
# Appointments missing the associated physician
|
||||||
|
ap9 = TestAppointment.create({ test_physician_id: 7777, test_patient_id: pa1.id, datetime: 3.months.ago })
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'deletes orphaned records on the specified key' do
|
||||||
|
expect { subject }.to change { TestAppointment.count }.by(-3)
|
||||||
|
|
||||||
|
# rubocop:disable Rails/WhereEquals
|
||||||
|
appointments_with_missing_patients = TestAppointment
|
||||||
|
.joins('LEFT OUTER JOIN test_patients ON test_patients.id = test_appointments.test_patient_id')
|
||||||
|
.where('test_patients.id IS NULL')
|
||||||
|
# rubocop:enable Rails/WhereEquals
|
||||||
|
expect(appointments_with_missing_patients.count).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'keeps orphaned records on another key' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
# rubocop:disable Rails/WhereEquals
|
||||||
|
appointments_with_missing_physicians = TestAppointment
|
||||||
|
.joins('LEFT OUTER JOIN test_physicians ON test_physicians.id = test_appointments.test_physician_id')
|
||||||
|
.where('test_physicians.id IS NULL')
|
||||||
|
# rubocop:enable Rails/WhereEquals
|
||||||
|
expect(appointments_with_missing_physicians.count).not_to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'keeps valid associated records' do
|
||||||
|
expect { subject }.not_to change { [TestPhysician.count, TestPatient.count] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there are no orphaned records' do
|
||||||
|
before(:each) do
|
||||||
|
phy1 = TestPhysician.create({ name: 'Ibn Sina' })
|
||||||
|
pa1 = TestPatient.create({ name: 'Chams ad-Dawla' })
|
||||||
|
ap1 = TestAppointment.create({ test_physician_id: phy1.id, test_patient_id: pa1.id, datetime: 2.months.ago })
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'doesn’t remove any records' do
|
||||||
|
expect { subject }.not_to change { [TestPhysician.count, TestPatient.count, TestAppointment.count] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '.add_concurrent_index' do
|
describe '.add_concurrent_index' do
|
||||||
let(:model) { ActiveRecord::Migration.new.extend(Database::MigrationHelpers) }
|
let(:model) { ActiveRecord::Migration.new.extend(Database::MigrationHelpers) }
|
||||||
|
|