From cf09d5bd63a6c886d0417163de2e966669c52809 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Thu, 30 Jun 2016 02:39:36 +0900 Subject: Move the warning about composite primary key to `AttributeMethods::PrimaryKey` Actually schema dumper/creation supports composite primary key (#21614). Therefore it should not show the warning about composite primary key in connection adapter. This change moves the warning to `AttributeMethods::PrimaryKey` and suppress the warning for habtm join table. Fixes #25388. --- .../associations/builder/has_and_belongs_to_many.rb | 6 ++++-- .../lib/active_record/attribute_methods/primary_key.rb | 15 ++++++++++++++- .../connection_adapters/abstract/schema_statements.rb | 11 +++-------- .../connection_adapters/postgresql/database_statements.rb | 8 ++++++++ activerecord/lib/active_record/schema_dumper.rb | 7 +------ .../has_and_belongs_to_many_associations_test.rb | 2 +- activerecord/test/cases/primary_keys_test.rb | 10 ++++++++-- 7 files changed, 39 insertions(+), 20 deletions(-) diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb index 5fbd79d118..dd5fd607a2 100644 --- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb @@ -76,8 +76,10 @@ module ActiveRecord::Associations::Builder # :nodoc: left_model.retrieve_connection end - def self.primary_key - false + private + + def self.suppress_composite_primary_key(pk) + pk unless pk.is_a?(Array) end } diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb index 0d5cb8b37c..d28edfb003 100644 --- a/activerecord/lib/active_record/attribute_methods/primary_key.rb +++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb @@ -95,7 +95,8 @@ module ActiveRecord base_name.foreign_key else if ActiveRecord::Base != self && table_exists? - connection.schema_cache.primary_keys(table_name) + pk = connection.schema_cache.primary_keys(table_name) + suppress_composite_primary_key(pk) else 'id' end @@ -122,6 +123,18 @@ module ActiveRecord @quoted_primary_key = nil @attributes_builder = nil end + + private + + def suppress_composite_primary_key(pk) + return pk unless pk.is_a?(Array) + + warn <<-WARNING.strip_heredoc + WARNING: Active Record does not support composite primary key. + + #{table_name} has composite primary key. Composite primary key is ignored. + WARNING + end end end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index eec0bc8518..b1b290ee36 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -129,14 +129,9 @@ module ActiveRecord # Returns just a table's primary key def primary_key(table_name) - pks = primary_keys(table_name) - warn <<-WARNING.strip_heredoc if pks.count > 1 - WARNING: Rails does not support composite primary key. - - #{table_name} has composite primary key. Composite primary key is ignored. - WARNING - - pks.first if pks.one? + pk = primary_keys(table_name) + pk = pk.first unless pk.size > 1 + pk end # Creates a new table with the name +table_name+. +table_name+ may either diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb index 6f2e03b370..f5232127c4 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb @@ -124,6 +124,8 @@ module ActiveRecord pk = primary_key(table_ref) if table_ref end + pk = suppress_composite_primary_key(pk) + if pk && use_insert_returning? sql = "#{sql} RETURNING #{quote_column_name(pk)}" end @@ -164,6 +166,12 @@ module ActiveRecord def exec_rollback_db_transaction execute "ROLLBACK" end + + private + + def suppress_composite_primary_key(pk) + pk unless pk.is_a?(Array) + end end end end diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb index d769376d1a..e8c176d603 100644 --- a/activerecord/lib/active_record/schema_dumper.rb +++ b/activerecord/lib/active_record/schema_dumper.rb @@ -105,12 +105,7 @@ HEADER tbl = StringIO.new # first dump primary key column - if @connection.respond_to?(:primary_keys) - pk = @connection.primary_keys(table) - pk = pk.first unless pk.size > 1 - else - pk = @connection.primary_key(table) - end + pk = @connection.primary_key(table) tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}" diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index 1bbca84bb2..e27f16b6e4 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -156,7 +156,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase warning = capture(:stderr) do country.treaties << treaty end - assert_no_match(/WARNING: Rails does not support composite primary key\./, warning) + assert_no_match(/WARNING: Active Record does not support composite primary key\./, warning) end def test_has_and_belongs_to_many diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb index 4267ad4a24..ea36c199f4 100644 --- a/activerecord/test/cases/primary_keys_test.rb +++ b/activerecord/test/cases/primary_keys_test.rb @@ -255,6 +255,7 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase def setup @connection = ActiveRecord::Base.connection + @connection.schema_cache.clear! @connection.create_table(:barcodes, primary_key: ["region", "code"], force: true) do |t| t.string :region t.integer :code @@ -270,10 +271,15 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase end def test_primary_key_issues_warning + model = Class.new(ActiveRecord::Base) do + def self.table_name + "barcodes" + end + end warning = capture(:stderr) do - assert_nil @connection.primary_key("barcodes") + assert_nil model.primary_key end - assert_match(/WARNING: Rails does not support composite primary key\./, warning) + assert_match(/WARNING: Active Record does not support composite primary key\./, warning) end def test_collectly_dump_composite_primary_key -- cgit v1.2.3