diff --git a/db/migrate/20231003000823494_add_foreign_key_to_spree_orders_spree_users_created_by_id.rb b/db/migrate/20231003000823494_add_foreign_key_to_spree_orders_spree_users_created_by_id.rb new file mode 100644 index 0000000000..0f5d46a849 --- /dev/null +++ b/db/migrate/20231003000823494_add_foreign_key_to_spree_orders_spree_users_created_by_id.rb @@ -0,0 +1,15 @@ +# Orphaned records can be found before running this migration with the following SQL: + +# SELECT COUNT(*) +# FROM spree_orders +# LEFT JOIN spree_users +# ON spree_orders.created_by_id = spree_users.id +# WHERE spree_users.id IS NULL +# AND spree_orders.created_by_id IS NOT NULL + + +class AddForeignKeyToSpreeOrdersSpreeUsersCreatedById < ActiveRecord::Migration[6.0] + def change + add_foreign_key :spree_orders, :spree_users, column: :created_by_id + end +end diff --git a/db/schema.rb b/db/schema.rb index cd2ed95af7..7e782b8747 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 20231002000137116) do +ActiveRecord::Schema[7.0].define(version: 20231003000823494) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" enable_extension "plpgsql" @@ -1157,6 +1157,7 @@ ActiveRecord::Schema[7.0].define(version: 20231002000137116) do add_foreign_key "spree_orders", "order_cycles", name: "spree_orders_order_cycle_id_fk" add_foreign_key "spree_orders", "spree_addresses", column: "bill_address_id", name: "spree_orders_bill_address_id_fk" add_foreign_key "spree_orders", "spree_addresses", column: "ship_address_id", name: "spree_orders_ship_address_id_fk" + add_foreign_key "spree_orders", "spree_users", column: "created_by_id" add_foreign_key "spree_orders", "spree_users", column: "user_id", name: "spree_orders_user_id_fk" add_foreign_key "spree_payments", "spree_orders", column: "order_id", name: "spree_payments_order_id_fk" add_foreign_key "spree_payments", "spree_payment_methods", column: "payment_method_id", name: "spree_payments_payment_method_id_fk" diff --git a/spec/models/database_spec.rb b/spec/models/database_spec.rb index 4e74fdd151..2731e145b8 100644 --- a/spec/models/database_spec.rb +++ b/spec/models/database_spec.rb @@ -104,11 +104,7 @@ RSpec.describe "Database" do migration_name = "add_foreign_key_to_#{model_class.table_name}_" \ "#{foreign_key_table_name}_#{foreign_key_column}" migration_class_name = migration_name.camelize - millisecond_timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S%L') - if millisecond_timestamp == @last_timestamp - millisecond_timestamp.to_i += 1 - end - @last_timestamp = millisecond_timestamp + millisecond_timestamp = generate_timestamp migration_file_name = "db/migrate/#{millisecond_timestamp}_" \ "#{migration_name}.rb" orphaned_records_query = generate_orphaned_records_query(model_class, foreign_key_table_name, @@ -144,4 +140,20 @@ RSpec.describe "Database" do # AND #{model_class.table_name}.#{foreign_key_column} IS NOT NULL SQL end + + # Generates a unique timestamp. + # + # We may create multiple migrations within the same second, maybe even millisecond. + # So we add precision to milliseconds and increment on conflict. + def generate_timestamp + @last_creation_time ||= Time.new.utc(0) + + creation_time = Time.now.utc + if creation_time <= @last_creation_time + creation_time += 0.001.seconds + end + @last_creation_time = creation_time + + creation_time.utc.strftime('%Y%m%d%H%M%S%L') + end end