diff --git a/.erb_lint.yml b/.erb_lint.yml
index 4bb191313..8b73dcd4d 100644
--- a/.erb_lint.yml
+++ b/.erb_lint.yml
@@ -11,6 +11,8 @@ linters:
- .rubocop.yml
Layout/InitialIndentation:
Enabled: false
+ Layout/LeadingEmptyLines:
+ Enabled: false
Layout/TrailingEmptyLines:
Enabled: false
Layout/TrailingWhitespace:
diff --git a/app/decorators/enclosure_decorator.rb b/app/decorators/enclosure_decorator.rb
new file mode 100644
index 000000000..467a1de95
--- /dev/null
+++ b/app/decorators/enclosure_decorator.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class EnclosureDecorator < ApplicationDecorator
+ def display_name
+ composants = object.composants.pluck(:name)
+
+ composants_sentence = if composants.empty?
+ "0 #{Composant.model_name.human(count: 0).downcase}"
+ else
+ composants.map { |c| c.presence || "n/c" }.to_sentence
+ end
+
+ "#{object.class.model_name.human} #{position} (#{composants_sentence})"
+ end
+end
diff --git a/app/models/cluster.rb b/app/models/cluster.rb
index 594791087..c1aa953dc 100644
--- a/app/models/cluster.rb
+++ b/app/models/cluster.rb
@@ -4,6 +4,7 @@ class Cluster < ApplicationRecord
has_changelog
has_many :servers, dependent: :restrict_with_error
+ has_many :cluster_rooms, dependent: :destroy
scope :sorted, -> { order(Arel.sql("LOWER(name)")) }
diff --git a/app/models/composant.rb b/app/models/composant.rb
index 179cb81c9..cc55e8649 100644
--- a/app/models/composant.rb
+++ b/app/models/composant.rb
@@ -7,7 +7,7 @@ class Composant < ApplicationRecord
belongs_to :enclosure
has_one :modele, through: :enclosure
- has_many :cards
+ has_many :cards, dependent: :restrict_with_error
validates :name, format: { without: /\s/ }, allow_blank: true
diff --git a/app/models/frame.rb b/app/models/frame.rb
index 41ccc7dc4..2068a9e7a 100644
--- a/app/models/frame.rb
+++ b/app/models/frame.rb
@@ -10,11 +10,14 @@ class Frame < ApplicationRecord # rubocop:disable Metrics/ClassLength
has_changelog
belongs_to :bay
+
+ has_one :islet, through: :bay
+ has_one :room, through: :islet
+
has_many :materials, -> { order("servers.position desc") }, class_name: "Server", dependent: :restrict_with_error
has_many :pdus, -> { only_pdus }, class_name: "Server", dependent: :restrict_with_error
has_many :servers, -> { no_pdus.order("servers.position desc") }, class_name: "Server", dependent: :restrict_with_error
- has_one :islet, through: :bay
- has_one :room, through: :islet
+
delegate :name, to: :room, prefix: true, allow_nil: true
validates :position, uniqueness: { scope: :bay_id }
diff --git a/app/models/modele.rb b/app/models/modele.rb
index aed1a560d..c822a1028 100644
--- a/app/models/modele.rb
+++ b/app/models/modele.rb
@@ -7,14 +7,15 @@ class Modele < ApplicationRecord
has_changelog
- has_many :servers, dependent: :restrict_with_error
- has_many :enclosures, dependent: :restrict_with_error
- has_many :composants, through: :enclosures
-
belongs_to :manufacturer, counter_cache: true
belongs_to :architecture, counter_cache: true
belongs_to :category, counter_cache: true
+ has_many :servers, dependent: :restrict_with_error
+ has_many :enclosures, dependent: :destroy
+ has_many :composants, through: :enclosures
+ has_many :cards, through: :composants
+
accepts_nested_attributes_for :enclosures,
allow_destroy: true,
reject_if: :all_blank
diff --git a/app/models/port_type.rb b/app/models/port_type.rb
index 3ba349040..4f220ad1c 100644
--- a/app/models/port_type.rb
+++ b/app/models/port_type.rb
@@ -3,7 +3,7 @@
class PortType < ApplicationRecord
has_changelog
- has_many :card_types
+ has_many :card_types, dependent: :restrict_with_error
scope :sorted, -> { order(name: :asc) }
diff --git a/app/models/server.rb b/app/models/server.rb
index 969dda200..2559b372f 100644
--- a/app/models/server.rb
+++ b/app/models/server.rb
@@ -19,7 +19,7 @@ class Server < ApplicationRecord # rubocop:disable Metrics/ClassLength
belongs_to :modele, counter_cache: true
has_one :manufacturer, through: :modele
- has_many :cards, -> { joins(:composant).includes(:composant) }
+ has_many :cards, -> { joins(:composant).includes(:composant) }, dependent: :destroy
has_many :card_types, through: :cards
has_many :ports, through: :cards
has_many :connections, through: :ports
diff --git a/app/views/clusters/destroy.html.erb b/app/views/clusters/destroy.html.erb
index b16c0ddff..eef0bf319 100644
--- a/app/views/clusters/destroy.html.erb
+++ b/app/views/clusters/destroy.html.erb
@@ -8,7 +8,8 @@
<%= render DeleteDependencyComponent.new(
- @cluster,
- confirmation_path: cluster_path(@cluster, confirm: true)
- ) %>
+ @cluster,
+ except: %i[cluster_rooms],
+ confirmation_path: cluster_path(@cluster, confirm: true),
+ ) %>
diff --git a/app/views/rooms/destroy.html.erb b/app/views/rooms/destroy.html.erb
index 1b866abe6..349b907a0 100644
--- a/app/views/rooms/destroy.html.erb
+++ b/app/views/rooms/destroy.html.erb
@@ -8,7 +8,8 @@
<%= render DeleteDependencyComponent.new(
- @room,
- confirmation_path: room_path(@room, confirm: true)
- ) %>
+ @room,
+ except: %i[cluster_rooms],
+ confirmation_path: room_path(@room, confirm: true),
+ ) %>
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index 363935bef..8970fcdf2 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -15,6 +15,9 @@ en:
one: Network hub cluster
other: Network hub clusters
color: Color
+ composant:
+ one: Component
+ other: Components
connection: Connection
contact: Contact
contact_assignment: Assignment
diff --git a/config/locales/activerecord.fr.yml b/config/locales/activerecord.fr.yml
index ac54850ea..bae8f8161 100644
--- a/config/locales/activerecord.fr.yml
+++ b/config/locales/activerecord.fr.yml
@@ -12,6 +12,9 @@ fr:
other: Châssis
modele: Modèle
category: Catégorie
+ composant:
+ one: Composant
+ other: Composants
air_conditioner: Climatisation
air_conditioner_model: Modèle de climatisation
architecture: Architecture
diff --git a/spec/decorators/enclosure_decorator_spec.rb b/spec/decorators/enclosure_decorator_spec.rb
new file mode 100644
index 000000000..fda834b6b
--- /dev/null
+++ b/spec/decorators/enclosure_decorator_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+describe EnclosureDecorator, type: :decorator do
+ let(:object) { enclosures(:one) }
+ let(:decorated_user) { described_class.new(object) }
+
+ describe "#display_name" do
+ it { expect(decorated_user.display_name).to eq("Enclosure 1 (compo1, compo2 et SL3)") }
+
+ context "without composants" do
+ let(:object) { Enclosure.new(position: 1) }
+
+ it { expect(decorated_user.display_name).to eq("Enclosure 1 (0 composant)") }
+ end
+
+ context "with composant with empty name" do
+ let(:object) { Enclosure.new(position: 1) }
+
+ before { allow(object).to receive(:composants).and_return([Composant.new]) }
+
+ it { expect(decorated_user.display_name).to eq("Enclosure 1 (n/c)") }
+ end
+ end
+end
diff --git a/spec/models/cluster_spec.rb b/spec/models/cluster_spec.rb
index edb0f6aec..f4999a9e3 100644
--- a/spec/models/cluster_spec.rb
+++ b/spec/models/cluster_spec.rb
@@ -8,7 +8,8 @@
it_behaves_like "changelogable", new_attributes: { name: "New name" }
describe "associations" do
- it { is_expected.to have_many(:servers) }
+ it { is_expected.to have_many(:servers).dependent(:restrict_with_error) }
+ it { is_expected.to have_many(:cluster_rooms).dependent(:destroy) }
end
describe "#to_s" do
diff --git a/spec/models/composant_spec.rb b/spec/models/composant_spec.rb
index 52ca9bebd..4a020dc68 100644
--- a/spec/models/composant_spec.rb
+++ b/spec/models/composant_spec.rb
@@ -11,7 +11,7 @@
describe "associations" do
it { is_expected.to belong_to(:enclosure) }
it { is_expected.to have_one(:modele).through(:enclosure) }
- it { is_expected.to have_many(:cards) }
+ it { is_expected.to have_many(:cards).dependent(:restrict_with_error) }
end
describe "validations" do
diff --git a/spec/models/frame_spec.rb b/spec/models/frame_spec.rb
index 855eee60b..5ee9c790c 100644
--- a/spec/models/frame_spec.rb
+++ b/spec/models/frame_spec.rb
@@ -12,9 +12,11 @@
it { is_expected.to belong_to(:bay) }
it { is_expected.to have_one(:islet).through(:bay) }
- it { is_expected.to have_many(:materials) }
- it { is_expected.to have_many(:pdus) }
- it { is_expected.to have_many(:servers) }
+ it { is_expected.to have_one(:room).through(:islet) }
+
+ it { is_expected.to have_many(:materials).dependent(:restrict_with_error) }
+ it { is_expected.to have_many(:pdus).dependent(:restrict_with_error) }
+ it { is_expected.to have_many(:servers).dependent(:restrict_with_error) }
end
describe "validations" do
diff --git a/spec/models/modele_spec.rb b/spec/models/modele_spec.rb
index 0dedc2476..9981edb50 100644
--- a/spec/models/modele_spec.rb
+++ b/spec/models/modele_spec.rb
@@ -11,9 +11,11 @@
it { is_expected.to belong_to(:manufacturer) }
it { is_expected.to belong_to(:architecture) }
it { is_expected.to belong_to(:category) }
- it { is_expected.to have_many(:servers) }
- it { is_expected.to have_many(:enclosures) }
+
+ it { is_expected.to have_many(:servers).dependent(:restrict_with_error) }
+ it { is_expected.to have_many(:enclosures).dependent(:destroy) }
it { is_expected.to have_many(:composants).through(:enclosures) }
+ it { is_expected.to have_many(:cards).through(:composants) }
end
describe "#validate_network_types_values" do
diff --git a/spec/models/port_type_spec.rb b/spec/models/port_type_spec.rb
index 5f8bf3a6b..ac92d93b0 100644
--- a/spec/models/port_type_spec.rb
+++ b/spec/models/port_type_spec.rb
@@ -8,7 +8,7 @@
it_behaves_like "changelogable", new_attributes: { name: "New name" }
describe "associations" do
- it { is_expected.to have_many(:card_types) }
+ it { is_expected.to have_many(:card_types).dependent(:restrict_with_error) }
end
describe "#is_power_input?" do
diff --git a/spec/models/server_spec.rb b/spec/models/server_spec.rb
index 5375838db..5a17c556c 100644
--- a/spec/models/server_spec.rb
+++ b/spec/models/server_spec.rb
@@ -22,7 +22,7 @@
it { is_expected.to have_one(:room).through(:islet) }
it { is_expected.to have_one(:manufacturer).through(:modele) }
- it { is_expected.to have_many(:cards) }
+ it { is_expected.to have_many(:cards).dependent(:destroy) }
it { is_expected.to have_many(:card_types).through(:cards) }
it { is_expected.to have_many(:ports).through(:cards) }
it { is_expected.to have_many(:connections).through(:ports) }