From 5c0df4e054a3857d19eae0efab84532a21e0ab4b Mon Sep 17 00:00:00 2001 From: Aidan Haran 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