mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
SQLite: Fix copy_table
with composite primary keys
`connection.primary_key` also return composite primary keys, so `from_primary_key_column` may not be found even if `from_primary_key` is presented. ``` % ARCONN=sqlite3 be ruby -w -Itest test/cases/adapters/sqlite3/sqlite3_adapter_test.rb -n test_copy_table_with_composite_primary_keys Using sqlite3 Run options: -n test_copy_table_with_composite_primary_keys --seed 19041 # Running: E Error: ActiveRecord::ConnectionAdapters::SQLite3AdapterTest#test_copy_table_with_composite_primary_keys: NoMethodError: undefined method `type' for nil:NilClass /path/to/rails/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb:411:in `block in copy_table' ``` This change fixes `copy_table` to do not lose composite primary keys.
This commit is contained in:
parent
e88e6cea21
commit
131cc6eab6
2 changed files with 35 additions and 6 deletions
|
@ -404,22 +404,24 @@ module ActiveRecord
|
|||
|
||||
def copy_table(from, to, options = {})
|
||||
from_primary_key = primary_key(from)
|
||||
from_primary_key_column = columns(from).select { |column| column.name == from_primary_key }.first
|
||||
options[:id] = false
|
||||
create_table(to, options) do |definition|
|
||||
@definition = definition
|
||||
@definition.primary_key(from_primary_key, from_primary_key_column.type) if from_primary_key.present?
|
||||
if from_primary_key.is_a?(Array)
|
||||
@definition.primary_keys from_primary_key
|
||||
end
|
||||
columns(from).each do |column|
|
||||
column_name = options[:rename] ?
|
||||
(options[:rename][column.name] ||
|
||||
options[:rename][column.name.to_sym] ||
|
||||
column.name) : column.name
|
||||
next if column_name == from_primary_key
|
||||
|
||||
@definition.column(column_name, column.type,
|
||||
limit: column.limit, default: column.default,
|
||||
precision: column.precision, scale: column.scale,
|
||||
null: column.null, collation: column.collation)
|
||||
null: column.null, collation: column.collation,
|
||||
primary_key: column_name == from_primary_key
|
||||
)
|
||||
end
|
||||
yield @definition if block_given?
|
||||
end
|
||||
|
|
|
@ -361,21 +361,48 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
class Barcode < ActiveRecord::Base
|
||||
self.primary_key = "code"
|
||||
end
|
||||
|
||||
def test_existing_records_have_custom_primary_key
|
||||
def test_copy_table_with_existing_records_have_custom_primary_key
|
||||
connection = Barcode.connection
|
||||
connection.create_table(:barcodes, primary_key: "code", id: :string, limit: 42, force: true) do |t|
|
||||
t.text :other_attr
|
||||
end
|
||||
code = "214fe0c2-dd47-46df-b53b-66090b3c1d40"
|
||||
Barcode.create! code: code, other_attr: "xxx"
|
||||
Barcode.create!(code: code, other_attr: "xxx")
|
||||
|
||||
connection.change_table "barcodes" do |t|
|
||||
connection.remove_column("barcodes", "other_attr")
|
||||
end
|
||||
|
||||
assert_equal code, Barcode.first.id
|
||||
ensure
|
||||
Barcode.reset_column_information
|
||||
end
|
||||
|
||||
def test_copy_table_with_composite_primary_keys
|
||||
connection = Barcode.connection
|
||||
connection.create_table(:barcodes, primary_key: ["region", "code"], force: true) do |t|
|
||||
t.string :region
|
||||
t.string :code
|
||||
t.text :other_attr
|
||||
end
|
||||
region = "US"
|
||||
code = "214fe0c2-dd47-46df-b53b-66090b3c1d40"
|
||||
Barcode.create!(region: region, code: code, other_attr: "xxx")
|
||||
|
||||
connection.change_table "barcodes" do |t|
|
||||
connection.remove_column("barcodes", "other_attr")
|
||||
end
|
||||
|
||||
assert_equal ["region", "code"], connection.primary_keys("barcodes")
|
||||
|
||||
barcode = Barcode.first
|
||||
assert_equal region, barcode.region
|
||||
assert_equal code, barcode.code
|
||||
ensure
|
||||
Barcode.reset_column_information
|
||||
end
|
||||
|
||||
def test_supports_extensions
|
||||
|
|
Loading…
Reference in a new issue