From 5c0df4e054a3857d19eae0efab84532a21e0ab4b Mon Sep 17 00:00:00 2001
From: Aidan Haran <aidanharan@yahoo.com>
Date: Tue, 20 May 2025 10:42:15 +0100
Subject: [PATCH] Enable identity insert on view's base table for fixtures

---
 CHANGELOG.md                                         |  6 ++++++
 .../sqlserver/database_statements.rb                 | 12 ++++++------
 test/cases/view_test_sqlserver.rb                    | 12 +++++++++---
 test/fixtures/sst_customers_view.yml                 |  6 ++++++
 4 files changed, 27 insertions(+), 9 deletions(-)
 create mode 100644 test/fixtures/sst_customers_view.yml

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c0553615f..2cb311960 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## Unreleased
+
+#### Fixed
+
+- [#1334](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1334) Enable identity insert on view's base table for fixtures.
+
 ## v8.0.6
 
 #### Fixed
diff --git a/lib/active_record/connection_adapters/sqlserver/database_statements.rb b/lib/active_record/connection_adapters/sqlserver/database_statements.rb
index 0473afb8e..f57978b6e 100644
--- a/lib/active_record/connection_adapters/sqlserver/database_statements.rb
+++ b/lib/active_record/connection_adapters/sqlserver/database_statements.rb
@@ -15,9 +15,6 @@ def write_query?(sql) # :nodoc:
 
         def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch:)
           result = if id_insert_table_name = query_requires_identity_insert?(sql)
-                     # If the table name is a view, we need to get the base table name for enabling identity insert.
-                     id_insert_table_name = view_table_name(id_insert_table_name) if view_exists?(id_insert_table_name)
-
                      with_identity_insert_enabled(id_insert_table_name, raw_connection) do
                        internal_exec_sql_query(sql, raw_connection)
                      end
@@ -225,11 +222,14 @@ def execute_procedure(proc_name, *variables)
         end
 
         def with_identity_insert_enabled(table_name, conn)
-          table_name = quote_table_name(table_name)
-          set_identity_insert(table_name, conn, true)
+          # If the table name is a view, we need to get the base table name for enabling identity insert.
+          table_name = view_table_name(table_name) if view_exists?(table_name)
+          quoted_table_name = quote_table_name(table_name)
+
+          set_identity_insert(quoted_table_name, conn, true)
           yield
         ensure
-          set_identity_insert(table_name, conn, false)
+          set_identity_insert(quoted_table_name, conn, false)
         end
 
         def use_database(database = nil)
diff --git a/test/cases/view_test_sqlserver.rb b/test/cases/view_test_sqlserver.rb
index 84bfd80e1..03b3fef87 100644
--- a/test/cases/view_test_sqlserver.rb
+++ b/test/cases/view_test_sqlserver.rb
@@ -48,11 +48,17 @@ class ViewTestSQLServer < ActiveRecord::TestCase
     end
   end
 
-  describe 'identity insert' do
-    it "identity insert works with views" do
-      assert_difference("SSTestCustomersView.count", 1) do
+  describe "identity insert" do
+    it "creates table record through a view" do
+      assert_difference("SSTestCustomersView.count", 2) do
         SSTestCustomersView.create!(id: 5, name: "Bob")
+        SSTestCustomersView.create!(id: 6, name: "Tim")
       end
     end
+
+    it "creates table records through a view using fixtures" do
+      ActiveRecord::FixtureSet.create_fixtures(File.join(ARTest::SQLServer.test_root_sqlserver, "fixtures"), ["sst_customers_view"])
+      assert_equal SSTestCustomersView.all.count, 2
+    end
   end
 end
diff --git a/test/fixtures/sst_customers_view.yml b/test/fixtures/sst_customers_view.yml
new file mode 100644
index 000000000..668ba3763
--- /dev/null
+++ b/test/fixtures/sst_customers_view.yml
@@ -0,0 +1,6 @@
+david:
+  name: "David"
+  balance: 2,004
+aidan:
+  name: "Aidan"
+  balance: 10,191