Merge pull request #47633 from Shopify/allow-deriving-composite-primary-key-from-schema
Allow composite primary key to be derived from schema
This commit is contained in:
commit
791f109d97
@ -1,3 +1,21 @@
|
||||
* Allow composite primary key to be derived from schema
|
||||
|
||||
Booting an application with a schema that contains composite primary keys
|
||||
will not issue warning and won't `nil`ify the `ActiveRecord::Base#primary_key` value anymore.
|
||||
|
||||
Given a `travel_routes` table definition and a `TravelRoute` model like:
|
||||
```ruby
|
||||
create_table :travel_routes, primary_key: [:origin, :destination], force: true do |t|
|
||||
t.string :origin
|
||||
t.string :destination
|
||||
end
|
||||
|
||||
class TravelRoute < ActiveRecord::Base; end
|
||||
```
|
||||
The `TravelRoute.primary_key` value will be automatically derived to `["origin", "destination"]`
|
||||
|
||||
*Nikita Vasilevsky*
|
||||
|
||||
* Include the `connection_pool` with exceptions raised from an adapter.
|
||||
|
||||
The `connection_pool` provides added context such as the connection used
|
||||
|
@ -133,8 +133,7 @@ def get_primary_key(base_name) # :nodoc:
|
||||
base_name.foreign_key
|
||||
else
|
||||
if ActiveRecord::Base != self && table_exists?
|
||||
pk = connection.schema_cache.primary_keys(table_name)
|
||||
suppress_composite_primary_key(pk)
|
||||
connection.schema_cache.primary_keys(table_name)
|
||||
else
|
||||
"id"
|
||||
end
|
||||
@ -178,16 +177,6 @@ def inherited(base)
|
||||
@quoted_primary_key = nil
|
||||
end
|
||||
end
|
||||
|
||||
def suppress_composite_primary_key(pk)
|
||||
return pk unless pk.is_a?(Array)
|
||||
|
||||
warn <<~WARNING
|
||||
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
|
||||
|
@ -166,19 +166,6 @@ def test_proper_usage_of_primary_keys_and_join_table
|
||||
assert_equal 1, country.treaties.count
|
||||
end
|
||||
|
||||
def test_join_table_composite_primary_key_should_not_warn
|
||||
country = Country.new(name: "India")
|
||||
country.country_id = "c1"
|
||||
country.save!
|
||||
|
||||
treaty = Treaty.new(name: "peace")
|
||||
treaty.treaty_id = "t1"
|
||||
warning = capture(:stderr) do
|
||||
country.treaties << treaty
|
||||
end
|
||||
assert_no_match(/WARNING: Active Record does not support composite primary key\./, warning)
|
||||
end
|
||||
|
||||
def test_has_and_belongs_to_many
|
||||
david = Developer.find(1)
|
||||
|
||||
|
@ -463,16 +463,16 @@ def test_id_predicate_composite
|
||||
end
|
||||
end
|
||||
|
||||
def test_primary_key_issues_warning
|
||||
model = Class.new(ActiveRecord::Base) do
|
||||
def self.table_name
|
||||
"uber_barcodes"
|
||||
def test_derives_composite_primary_key
|
||||
def test_primary_key_issues_warning
|
||||
model = Class.new(ActiveRecord::Base) do
|
||||
def self.table_name
|
||||
"uber_barcodes"
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal ["region", "code"], model.primary_key
|
||||
end
|
||||
warning = capture(:stderr) do
|
||||
assert_nil model.primary_key
|
||||
end
|
||||
assert_match(/WARNING: Active Record does not support composite primary key\./, warning)
|
||||
end
|
||||
|
||||
def test_collectly_dump_composite_primary_key
|
||||
|
@ -3,7 +3,6 @@
|
||||
module Cpk
|
||||
class Book < ActiveRecord::Base
|
||||
self.table_name = :cpk_books
|
||||
self.primary_key = [:author_id, :number]
|
||||
|
||||
belongs_to :order, autosave: true, query_constraints: [:shop_id, :order_id]
|
||||
belongs_to :author, class_name: "Cpk::Author"
|
||||
|
@ -3,6 +3,8 @@
|
||||
module Cpk
|
||||
class Order < ActiveRecord::Base
|
||||
self.table_name = :cpk_orders
|
||||
# explicit definition is to allow schema definition to be simplified
|
||||
# to be shared between different databases
|
||||
self.primary_key = [:shop_id, :id]
|
||||
|
||||
has_many :order_agreements, primary_key: :id
|
||||
|
Loading…
Reference in New Issue
Block a user