Skip to content

Commit 449838a

Browse files
committed
Add inverse_of to state/address, add FK constraint
For the database, a state is optional on an address. What this commit ensures is that any state ID entered into the `state_id` column on `spree_addresses` is actually present in the `spree_states` table.
1 parent 7e8765b commit 449838a

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

core/app/models/spree/state.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module Spree
44
class State < Spree::Base
55
belongs_to :country, class_name: 'Spree::Country'
6-
has_many :addresses, dependent: :nullify
6+
has_many :addresses, dependent: :nullify, inverse_of: :state
77

88
validates :name, presence: true
99

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# frozen_string_literal: true
2+
3+
class AddStateForeignKeys < ActiveRecord::Migration[7.0]
4+
def up
5+
# Uncomment the following code to remove orphaned records if this migration fails
6+
#
7+
# say_with_time "Resetting state IDs on addresses where the state record is no longer present" do
8+
# Spree::Address.where.not(state_id: nil).left_joins(:state).where(spree_states: { id: nil }).update_all(state_id: nil)
9+
# end
10+
11+
add_foreign_key :spree_addresses, :spree_states, column: :state_id, null: true, on_delete: :restrict
12+
rescue ActiveRecord::StatementInvalid => e
13+
if e.cause.is_a?(PG::ForeignKeyViolation) || e.cause.is_a?(Mysql2::Error) || e.cause.is_a?(SQLite3::ConstraintException)
14+
Rails.logger.warn <<~MSG
15+
⚠️ Foreign key constraint failed when adding :spree_addresses => :spree_states.
16+
To fix this:
17+
1. Uncomment the code that removes orphaned records.
18+
2. Rerun the migration.
19+
Offending error: #{e.cause.class} - #{e.cause.message}
20+
MSG
21+
end
22+
raise
23+
end
24+
25+
def down
26+
remove_foreign_key :spree_addresses, :spree_states, column: :state_id, null: true, on_delete: :restrict
27+
end
28+
end

0 commit comments

Comments
 (0)