From 80130fb7d1e97e094c5fb2bf0cd0f6bb08b869c4 Mon Sep 17 00:00:00 2001 From: cryptogopher Date: Sun, 22 Feb 2026 17:50:43 +0100 Subject: [PATCH] Allow cascade delete Unit/Quantity Closes #32 --- app/models/unit.rb | 3 ++- app/models/user.rb | 6 +++--- db/migrate/20230602185352_create_units.rb | 2 +- db/migrate/20250104194343_create_quantities.rb | 2 +- db/schema.rb | 4 ++-- db/seeds/templates/units.erb | 2 +- db/seeds/units.rb | 2 +- test/system/units_test.rb | 12 ++++++------ test/system/users_test.rb | 3 ++- 9 files changed, 19 insertions(+), 17 deletions(-) diff --git a/app/models/unit.rb b/app/models/unit.rb index 5fad8e7..18ef123 100644 --- a/app/models/unit.rb +++ b/app/models/unit.rb @@ -3,7 +3,8 @@ class Unit < ApplicationRecord belongs_to :user, optional: true belongs_to :base, optional: true, class_name: "Unit" - has_many :subunits, class_name: "Unit", inverse_of: :base, dependent: :restrict_with_error + has_many :subunits, class_name: "Unit", inverse_of: :base, + dependent: :restrict_with_error validate if: ->{ base.present? } do errors.add(:base, :user_mismatch) unless user_id == base.user_id diff --git a/app/models/user.rb b/app/models/user.rb index f113f3b..0de9460 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -12,10 +12,10 @@ class User < ApplicationRecord disabled: 0, # administratively disallowed to sign in }, default: :active, validate: true - has_many :readouts, dependent: :destroy + has_many :readouts, dependent: :delete_all accepts_nested_attributes_for :readouts - has_many :quantities, dependent: :destroy - has_many :units, dependent: :destroy + has_many :quantities, dependent: :delete_all + has_many :units, dependent: :delete_all validates :email, presence: true, uniqueness: true, length: {maximum: type_for_attribute(:email).limit} diff --git a/db/migrate/20230602185352_create_units.rb b/db/migrate/20230602185352_create_units.rb index af0cc04..089fe62 100644 --- a/db/migrate/20230602185352_create_units.rb +++ b/db/migrate/20230602185352_create_units.rb @@ -5,7 +5,7 @@ class CreateUnits < ActiveRecord::Migration[7.0] t.string :symbol, null: false, limit: 15 t.text :description t.decimal :multiplier, null: false, precision: 30, scale: 15, default: 1.0 - t.references :base, foreign_key: {to_table: :units} + t.references :base, foreign_key: {to_table: :units, on_delete: :cascade} t.timestamps null: false end diff --git a/db/migrate/20250104194343_create_quantities.rb b/db/migrate/20250104194343_create_quantities.rb index 16292c2..7e1a0ee 100644 --- a/db/migrate/20250104194343_create_quantities.rb +++ b/db/migrate/20250104194343_create_quantities.rb @@ -4,7 +4,7 @@ class CreateQuantities < ActiveRecord::Migration[7.2] t.references :user, foreign_key: true t.string :name, null: false, limit: 31 t.text :description - t.references :parent, foreign_key: {to_table: :quantities} + t.references :parent, foreign_key: {to_table: :quantities, on_delete: :cascade} t.timestamps null: false diff --git a/db/schema.rb b/db/schema.rb index f4c56c6..3975ec5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -69,11 +69,11 @@ ActiveRecord::Schema[7.2].define(version: 2025_01_21_230456) do t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end - add_foreign_key "quantities", "quantities", column: "parent_id" + add_foreign_key "quantities", "quantities", column: "parent_id", on_delete: :cascade add_foreign_key "quantities", "users" add_foreign_key "readouts", "quantities" add_foreign_key "readouts", "units" add_foreign_key "readouts", "users" - add_foreign_key "units", "units", column: "base_id" + add_foreign_key "units", "units", column: "base_id", on_delete: :cascade add_foreign_key "units", "users" end diff --git a/db/seeds/templates/units.erb b/db/seeds/templates/units.erb index 8d4566f..cfec373 100644 --- a/db/seeds/templates/units.erb +++ b/db/seeds/templates/units.erb @@ -1,5 +1,5 @@ Unit.transaction do - Unit.defaults.order(Unit.arel_table[:base_id].eq(nil)).delete_all + Unit.defaults.delete_all units = {} <% Unit.defaults.ordered.each do |unit| %> <%= "\n" if unit.base.nil? %> diff --git a/db/seeds/units.rb b/db/seeds/units.rb index 1542066..0ca9242 100644 --- a/db/seeds/units.rb +++ b/db/seeds/units.rb @@ -1,5 +1,5 @@ Unit.transaction do - Unit.defaults.order(Unit.arel_table[:base_id].eq(nil)).delete_all + Unit.defaults.delete_all units = {} diff --git a/test/system/units_test.rb b/test/system/units_test.rb index 0c939f2..f015a41 100644 --- a/test/system/units_test.rb +++ b/test/system/units_test.rb @@ -6,14 +6,14 @@ require "application_system_test_case" # * user with no units class UnitsTest < ApplicationSystemTestCase - LINK_LABELS = { - new_unit: t('units.index.new_unit'), - new_subunit: t('units.unit.new_subunit'), - edit: nil - } + LINK_LABELS = {} setup do @user = sign_in + + LINK_LABELS.clear + LINK_LABELS[:new_unit] = t('units.index.new_unit') + LINK_LABELS[:new_subunit] = t('units.unit.new_subunit') LINK_LABELS[:edit] = Regexp.union(@user.units.map(&:symbol)) visit units_path @@ -26,7 +26,7 @@ class UnitsTest < ApplicationSystemTestCase end # Cannot #destroy_all due to {dependent: :restrict*} on Unit.subunits association - @user.units.order(Unit.arel_table[:base_id].eq(nil)).delete_all + @user.units.delete_all visit units_path within 'tbody' do assert_selector 'tr', count: 1 diff --git a/test/system/users_test.rb b/test/system/users_test.rb index edefe81..ad362cd 100644 --- a/test/system/users_test.rb +++ b/test/system/users_test.rb @@ -157,8 +157,9 @@ class UsersTest < ApplicationSystemTestCase end assert_difference ->{ User.count }, -1 do accept_confirm { click_on t("users.registrations.edit.delete") } + assert_current_path new_user_session_path end - assert_current_path new_user_session_path + assert_text t("devise.registrations.destroyed") end test "index forbidden for non admin" do