aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actioncable/lib/action_cable/connection/base.rb5
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb2
-rw-r--r--actionview/lib/action_view/helpers/url_helper.rb7
-rw-r--r--activemodel/lib/active_model/model.rb4
-rw-r--r--activerecord/CHANGELOG.md4
-rw-r--r--activerecord/lib/active_record/autosave_association.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb15
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb33
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/column.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb23
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb13
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb13
-rw-r--r--activerecord/lib/active_record/errors.rb32
-rw-r--r--activerecord/lib/active_record/migration/compatibility.rb11
-rw-r--r--activerecord/test/cases/adapter_test.rb8
-rw-r--r--activerecord/test/cases/adapters/mysql2/active_schema_test.rb3
-rw-r--r--activerecord/test/cases/adapters/mysql2/legacy_migration_test.rb60
-rw-r--r--activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb13
-rw-r--r--activerecord/test/cases/adapters/postgresql/active_schema_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/legacy_migration_test.rb54
-rw-r--r--activerecord/test/cases/adapters/sqlite3/legacy_migration_test.rb59
-rw-r--r--activerecord/test/cases/autosave_association_test.rb24
-rw-r--r--activerecord/test/cases/comment_test.rb3
-rw-r--r--activerecord/test/cases/defaults_test.rb2
-rw-r--r--activerecord/test/cases/migration/change_schema_test.rb18
-rw-r--r--activerecord/test/cases/migration/change_table_test.rb7
-rw-r--r--activerecord/test/cases/migration/foreign_key_test.rb6
-rw-r--r--activerecord/test/cases/migration/references_foreign_key_test.rb8
-rw-r--r--activerecord/test/cases/primary_keys_test.rb121
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb2
-rw-r--r--activerecord/test/schema/schema.rb9
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/puma.rb12
39 files changed, 507 insertions, 110 deletions
diff --git a/actioncable/lib/action_cable/connection/base.rb b/actioncable/lib/action_cable/connection/base.rb
index dfee123ea2..e1da126d64 100644
--- a/actioncable/lib/action_cable/connection/base.rb
+++ b/actioncable/lib/action_cable/connection/base.rb
@@ -24,11 +24,8 @@ module ActionCable
#
# protected
# def find_verified_user
- # if current_user = User.find_by_identity cookies.signed[:identity_id]
- # current_user
- # else
+ # User.find_by_identity(cookies.signed[:identity_id]) ||
# reject_unauthorized_connection
- # end
# end
# end
# end
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index e971917ca2..56cfb4fbba 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -67,7 +67,7 @@ module ActionController
end
def _set_rendered_content_type(format)
- unless response.content_type
+ if format && !response.content_type
self.content_type = format.to_s
end
end
diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb
index 1277126995..22cc4b2920 100644
--- a/actionview/lib/action_view/helpers/url_helper.rb
+++ b/actionview/lib/action_view/helpers/url_helper.rb
@@ -105,10 +105,9 @@ module ActionView
# driver to prompt with the question specified (in this case, the
# resulting text would be <tt>question?</tt>. If the user accepts, the
# link is processed normally, otherwise no action is taken.
- # * <tt>:disable_with</tt> - Value of this parameter will be
- # used as the value for a disabled version of the submit
- # button when the form is submitted. This feature is provided
- # by the unobtrusive JavaScript driver.
+ # * <tt>:disable_with</tt> - Value of this parameter will be used as the
+ # name for a disabled version of the link. This feature is provided by
+ # the unobtrusive JavaScript driver.
#
# ==== Examples
# Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
diff --git a/activemodel/lib/active_model/model.rb b/activemodel/lib/active_model/model.rb
index e683050787..945a5402a3 100644
--- a/activemodel/lib/active_model/model.rb
+++ b/activemodel/lib/active_model/model.rb
@@ -2,10 +2,10 @@ module ActiveModel
# == Active \Model \Basic \Model
#
# Includes the required interface for an object to interact with
- # <tt>ActionPack</tt>, using different <tt>ActiveModel</tt> modules.
+ # Action Pack and Action View, using different Active Model modules.
# It includes model name introspections, conversions, translations and
# validations. Besides that, it allows you to initialize the object with a
- # hash of attributes, pretty much like <tt>ActiveRecord</tt> does.
+ # hash of attributes, pretty much like Active Record does.
#
# A minimal implementation could be:
#
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 96d0ad3b30..2182ee78bb 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,7 @@
+* PostgreSQL & MySQL: Use big integer as primary key type for new tables
+
+ *Jon McCartie*, *Pavel Pravosud*
+
* Change the type argument of `ActiveRecord::Base#attribute` to be optional.
The default is now `ActiveRecord::Type::Value.new`, which provides no type
casting behavior.
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index b343332bae..9d0b501862 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -383,6 +383,9 @@ module ActiveRecord
if association = association_instance_get(reflection.name)
autosave = reflection.options[:autosave]
+ # reconstruct the scope now that we know the owner's id
+ association.reset_scope if association.respond_to?(:reset_scope)
+
if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
if autosave
records_to_destroy = records.select(&:marked_for_destruction?)
@@ -408,9 +411,6 @@ module ActiveRecord
raise ActiveRecord::Rollback unless saved
end
end
-
- # reconstruct the scope now that we know the owner's id
- association.reset_scope if association.respond_to?(:reset_scope)
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index 83d1d7cd01..f783b1941b 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -71,7 +71,7 @@ module ActiveRecord
polymorphic: false,
index: true,
foreign_key: false,
- type: :integer,
+ type: :bigint,
**options
)
@name = name
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
index dabccc00bb..b912d24626 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
@@ -56,7 +56,7 @@ module ActiveRecord
private
def default_primary_key?(column)
- schema_type(column) == :integer
+ schema_type(column) == :bigint
end
def schema_type(column)
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 151629b02a..5623257fe8 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -996,15 +996,13 @@ module ActiveRecord
def insert_versions_sql(versions) # :nodoc:
sm_table = ActiveRecord::Migrator.schema_migrations_table_name
- if supports_multi_insert?
+ if versions.is_a?(Array)
sql = "INSERT INTO #{sm_table} (version) VALUES\n"
sql << versions.map { |v| "('#{v}')" }.join(",\n")
sql << ";\n\n"
sql
else
- versions.map { |version|
- "INSERT INTO #{sm_table} (version) VALUES ('#{version}');"
- }.join "\n\n"
+ "INSERT INTO #{sm_table} (version) VALUES ('#{versions}');"
end
end
@@ -1042,7 +1040,13 @@ module ActiveRecord
if (duplicate = inserting.detect { |v| inserting.count(v) > 1 })
raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
end
- execute insert_versions_sql(inserting)
+ if supports_multi_insert?
+ execute insert_versions_sql(inserting)
+ else
+ inserting.each do |v|
+ execute insert_versions_sql(v)
+ end
+ end
end
end
@@ -1171,6 +1175,7 @@ module ActiveRecord
if order = options[:order]
case order
when Hash
+ order = order.symbolize_keys
quoted_columns.each { |name, column| column << " #{order[name].upcase}" if order[name].present? }
when String
quoted_columns.each { |name, column| column << " #{order.upcase}" if order.present? }
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 98152853c2..0e4bc1afcb 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -39,7 +39,7 @@ module ActiveRecord
self.emulate_booleans = true
NATIVE_DATABASE_TYPES = {
- primary_key: "int auto_increment PRIMARY KEY",
+ primary_key: "BIGINT(8) UNSIGNED auto_increment PRIMARY KEY",
string: { name: "varchar", limit: 255 },
text: { name: "text", limit: 65535 },
integer: { name: "int", limit: 4 },
@@ -717,6 +717,7 @@ module ActiveRecord
if length = options[:length]
case length
when Hash
+ length = length.symbolize_keys
quoted_columns.each { |name, column| column << "(#{length[name]})" if length[name].present? }
when Integer
quoted_columns.each { |name, column| column << "(#{length})" }
@@ -733,9 +734,13 @@ module ActiveRecord
# See https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
ER_DUP_ENTRY = 1062
+ ER_NOT_NULL_VIOLATION = 1048
+ ER_DO_NOT_HAVE_DEFAULT = 1364
ER_NO_REFERENCED_ROW_2 = 1452
ER_DATA_TOO_LONG = 1406
ER_LOCK_DEADLOCK = 1213
+ ER_CANNOT_ADD_FOREIGN = 1215
+ ER_CANNOT_CREATE_TABLE = 1005
def translate_exception(exception, message)
case error_number(exception)
@@ -743,8 +748,18 @@ module ActiveRecord
RecordNotUnique.new(message)
when ER_NO_REFERENCED_ROW_2
InvalidForeignKey.new(message)
+ when ER_CANNOT_ADD_FOREIGN
+ mismatched_foreign_key(message)
+ when ER_CANNOT_CREATE_TABLE
+ if message.include?("errno: 150")
+ mismatched_foreign_key(message)
+ else
+ super
+ end
when ER_DATA_TOO_LONG
ValueTooLong.new(message)
+ when ER_NOT_NULL_VIOLATION, ER_DO_NOT_HAVE_DEFAULT
+ NotNullViolation.new(message)
when ER_LOCK_DEADLOCK
Deadlocked.new(message)
else
@@ -769,6 +784,10 @@ module ActiveRecord
options[:null] = column.null
end
+ unless options.key?(:comment)
+ options[:comment] = column.comment
+ end
+
td = create_table_definition(table_name)
cd = td.new_column_definition(column.name, type, options)
schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
@@ -910,6 +929,18 @@ module ActiveRecord
MySQL::TableDefinition.new(*args)
end
+ def mismatched_foreign_key(message)
+ parts = message.scan(/`(\w+)`[ $)]/).flatten
+ MismatchedForeignKey.new(
+ self,
+ message: message,
+ table: parts[0],
+ foreign_key: parts[1],
+ target_table: parts[2],
+ primary_key: parts[3],
+ )
+ end
+
def extract_schema_qualified_name(string) # :nodoc:
schema, name = string.to_s.scan(/[^`.\s]+|`[^`]*`/)
schema, name = @config[:database], schema unless name
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/column.rb b/activerecord/lib/active_record/connection_adapters/mysql/column.rb
index 22b9df5309..c66d543752 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/column.rb
@@ -5,6 +5,7 @@ module ActiveRecord
delegate :extra, to: :sql_type_metadata, allow_nil: true
def unsigned?
+ # enum and set types do not allow being defined as unsigned.
!/\A(?:enum|set)\b/.match?(sql_type) && /\bunsigned\b/.match?(sql_type)
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb
index ce773ed75b..0cf40de70f 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb
@@ -3,7 +3,10 @@ module ActiveRecord
module MySQL
module ColumnMethods
def primary_key(name, type = :primary_key, **options)
- options[:auto_increment] = true if type == :bigint && !options.key?(:default)
+ if type == :primary_key && !options.key?(:default)
+ options[:auto_increment] = true
+ options[:limit] = 8
+ end
super
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
index 9b02d8a34b..2065816501 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
@@ -3,11 +3,9 @@ module ActiveRecord
module MySQL
module ColumnDumper
def column_spec_for_primary_key(column)
- if column.bigint?
- spec = { id: :bigint.inspect }
- spec[:default] = schema_default(column) || "nil" unless column.auto_increment?
- else
- spec = super
+ spec = super
+ if column.type == :integer && !column.auto_increment?
+ spec[:default] = schema_default(column) || "nil"
end
spec[:unsigned] = "true" if column.unsigned?
spec
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
index ae1ec3e2b7..4afb4733eb 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
@@ -42,7 +42,16 @@ module ActiveRecord
# a record (as primary keys cannot be +nil+). This might be done via the
# +SecureRandom.uuid+ method and a +before_save+ callback, for instance.
def primary_key(name, type = :primary_key, **options)
- options[:default] = options.fetch(:default, "gen_random_uuid()") if type == :uuid
+ if type == :uuid
+ options[:default] = options.fetch(:default, "gen_random_uuid()")
+ elsif options.delete(:auto_increment) == true && %i(integer bigint).include?(type)
+ type = if type == :bigint || options[:limit] == 8
+ :bigserial
+ else
+ :serial
+ end
+ end
+
super
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb
index c20baf655c..7808d37deb 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb
@@ -25,7 +25,7 @@ module ActiveRecord
private
def default_primary_key?(column)
- schema_type(column) == :serial
+ schema_type(column) == :bigserial
end
def schema_type(column)
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 28e80a084a..5262141995 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -70,7 +70,7 @@ module ActiveRecord
ADAPTER_NAME = "PostgreSQL".freeze
NATIVE_DATABASE_TYPES = {
- primary_key: "serial primary key",
+ primary_key: "bigserial primary key",
string: { name: "character varying" },
text: { name: "text" },
integer: { name: "integer" },
@@ -408,6 +408,7 @@ module ActiveRecord
# See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
VALUE_LIMIT_VIOLATION = "22001"
+ NOT_NULL_VIOLATION = "23502"
FOREIGN_KEY_VIOLATION = "23503"
UNIQUE_VIOLATION = "23505"
SERIALIZATION_FAILURE = "40001"
@@ -423,6 +424,8 @@ module ActiveRecord
InvalidForeignKey.new(message)
when VALUE_LIMIT_VIOLATION
ValueTooLong.new(message)
+ when NOT_NULL_VIOLATION
+ NotNullViolation.new(message)
when SERIALIZATION_FAILURE
SerializationFailure.new(message)
when DEADLOCK_DETECTED
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb
new file mode 100644
index 0000000000..d0b38dff4c
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb
@@ -0,0 +1,23 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module SQLite3
+ module ColumnMethods
+ def primary_key(name, type = :primary_key, **options)
+ if options.delete(:auto_increment) == true && %i(integer bigint).include?(type)
+ type = :primary_key
+ end
+
+ super
+ end
+ end
+
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
+ include ColumnMethods
+ end
+
+ class Table < ActiveRecord::ConnectionAdapters::Table
+ include ColumnMethods
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb
new file mode 100644
index 0000000000..c027fef83c
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb
@@ -0,0 +1,13 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module SQLite3
+ module ColumnDumper
+ private
+
+ def default_primary_key?(column)
+ schema_type(column) == :integer
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 0493ab4e4b..a7c4a2cd86 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -3,6 +3,8 @@ require "active_record/connection_adapters/statement_pool"
require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
require "active_record/connection_adapters/sqlite3/quoting"
require "active_record/connection_adapters/sqlite3/schema_creation"
+require "active_record/connection_adapters/sqlite3/schema_definitions"
+require "active_record/connection_adapters/sqlite3/schema_dumper"
gem "sqlite3", "~> 1.3.6"
require "sqlite3"
@@ -52,6 +54,7 @@ module ActiveRecord
ADAPTER_NAME = "SQLite".freeze
include SQLite3::Quoting
+ include SQLite3::ColumnDumper
NATIVE_DATABASE_TYPES = {
primary_key: "INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL",
@@ -75,6 +78,10 @@ module ActiveRecord
end
end
+ def update_table_definition(table_name, base) # :nodoc:
+ SQLite3::Table.new(table_name, base)
+ end
+
def schema_creation # :nodoc:
SQLite3::SchemaCreation.new self
end
@@ -523,6 +530,8 @@ module ActiveRecord
# column *column_name* is not unique
when /column(s)? .* (is|are) not unique/, /UNIQUE constraint failed: .*/
RecordNotUnique.new(message)
+ when /.* may not be NULL/, /NOT NULL constraint failed: .*/
+ NotNullViolation.new(message)
else
super
end
@@ -569,6 +578,10 @@ module ActiveRecord
basic_structure.to_hash
end
end
+
+ def create_table_definition(*args)
+ SQLite3::TableDefinition.new(*args)
+ end
end
end
end
diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb
index 6464d40c94..507615a222 100644
--- a/activerecord/lib/active_record/errors.rb
+++ b/activerecord/lib/active_record/errors.rb
@@ -123,6 +123,38 @@ module ActiveRecord
class InvalidForeignKey < WrappedDatabaseException
end
+ # Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
+ class MismatchedForeignKey < StatementInvalid
+ def initialize(adapter = nil, message: nil, table: nil, foreign_key: nil, target_table: nil, primary_key: nil)
+ @adapter = adapter
+ if table
+ msg = <<-EOM.strip_heredoc
+ Column `#{foreign_key}` on table `#{table}` has a type of `#{column_type(table, foreign_key)}`.
+ This does not match column `#{primary_key}` on `#{target_table}`, which has type `#{column_type(target_table, primary_key)}`.
+ To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :integer. (For example `t.integer #{foreign_key}`).
+ EOM
+ else
+ msg = <<-EOM
+ There is a mismatch between the foreign key and primary key column types.
+ Verify that the foreign key column type and the primary key of the associated table match types.
+ EOM
+ end
+ if message
+ msg << "\nOriginal message: #{message}"
+ end
+ super(msg)
+ end
+
+ private
+ def column_type(table, column)
+ @adapter.columns(table).detect { |c| c.name == column }.sql_type
+ end
+ end
+
+ # Raised when a record cannot be inserted or updated because it would violate a not null constraint.
+ class NotNullViolation < StatementInvalid
+ end
+
# Raised when a record cannot be inserted or updated because a value too long for a column type.
class ValueTooLong < StatementInvalid
end
diff --git a/activerecord/lib/active_record/migration/compatibility.rb b/activerecord/lib/active_record/migration/compatibility.rb
index ae45ac7157..9c357e1604 100644
--- a/activerecord/lib/active_record/migration/compatibility.rb
+++ b/activerecord/lib/active_record/migration/compatibility.rb
@@ -104,11 +104,20 @@ module ActiveRecord
class V5_0 < V5_1
def create_table(table_name, options = {})
- if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
+ if adapter_name == "PostgreSQL"
if options[:id] == :uuid && !options[:default]
options[:default] = "uuid_generate_v4()"
end
end
+
+ # Since 5.1 Postgres adapter uses bigserial type for primary
+ # keys by default and MySQL uses bigint. This compat layer makes old migrations utilize
+ # serial/int type instead -- the way it used to work before 5.1.
+ if options[:id].blank?
+ options[:id] = :integer
+ options[:auto_increment] = true
+ end
+
super
end
end
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index 8bcecf2ed3..2f0e8d866d 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -182,6 +182,14 @@ module ActiveRecord
assert_not_nil error.cause
end
+ def test_not_null_violations_are_translated_to_specific_exception
+ error = assert_raises(ActiveRecord::NotNullViolation) do
+ Post.create
+ end
+
+ assert_not_nil error.cause
+ end
+
unless current_adapter?(:SQLite3Adapter)
def test_foreign_key_violations_are_translated_to_specific_exception
error = assert_raises(ActiveRecord::InvalidForeignKey) do
diff --git a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
index a70eb5a094..2a528b2cb1 100644
--- a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb
@@ -28,12 +28,15 @@ class Mysql2ActiveSchemaTest < ActiveRecord::Mysql2TestCase
expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(15)) "
assert_equal expected, add_index(:people, [:last_name, :first_name], length: 15)
+ assert_equal expected, add_index(:people, ["last_name", "first_name"], length: 15)
expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`) "
assert_equal expected, add_index(:people, [:last_name, :first_name], length: { last_name: 15 })
+ assert_equal expected, add_index(:people, ["last_name", "first_name"], length: { last_name: 15 })
expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(10)) "
assert_equal expected, add_index(:people, [:last_name, :first_name], length: { last_name: 15, first_name: 10 })
+ assert_equal expected, add_index(:people, ["last_name", :first_name], length: { last_name: 15, "first_name" => 10 })
%w(SPATIAL FULLTEXT UNIQUE).each do |type|
expected = "CREATE #{type} INDEX `index_people_on_last_name` ON `people` (`last_name`) "
diff --git a/activerecord/test/cases/adapters/mysql2/legacy_migration_test.rb b/activerecord/test/cases/adapters/mysql2/legacy_migration_test.rb
new file mode 100644
index 0000000000..5d3125c2be
--- /dev/null
+++ b/activerecord/test/cases/adapters/mysql2/legacy_migration_test.rb
@@ -0,0 +1,60 @@
+require "cases/helper"
+
+class MysqlLegacyMigrationTest < ActiveRecord::Mysql2TestCase
+ self.use_transactional_tests = false
+
+ class GenerateTableWithoutBigint < ActiveRecord::Migration[5.0]
+ def change
+ create_table :legacy_integer_pk do |table|
+ table.string :foo
+ end
+
+ create_table :override_pk, id: :bigint do |table|
+ table.string :bar
+ end
+ end
+ end
+
+ def setup
+ super
+ @connection = ActiveRecord::Base.connection
+
+ @migration_verbose_old = ActiveRecord::Migration.verbose
+ ActiveRecord::Migration.verbose = false
+
+ migrations = [GenerateTableWithoutBigint.new(nil, 1)]
+
+ ActiveRecord::Migrator.new(:up, migrations).migrate
+ end
+
+ def teardown
+ ActiveRecord::Migration.verbose = @migration_verbose_old
+ @connection.drop_table("legacy_integer_pk")
+ @connection.drop_table("override_pk")
+ ActiveRecord::SchemaMigration.delete_all rescue nil
+ super
+ end
+
+ def test_create_table_uses_integer_as_pkey_by_default
+ col = column(:legacy_integer_pk, :id)
+ assert_equal "int(11)", sql_type_for(col)
+ assert col.auto_increment?
+ end
+
+ def test_create_tables_respects_pk_column_type_override
+ col = column(:override_pk, :id)
+ assert_equal "bigint(20)", sql_type_for(col)
+ end
+
+ private
+
+ def column(table_name, column_name)
+ ActiveRecord::Base.connection
+ .columns(table_name.to_s)
+ .detect { |c| c.name == column_name.to_s }
+ end
+
+ def sql_type_for(col)
+ col && col.sql_type
+ end
+end
diff --git a/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb b/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
index 69336eb906..aab3dcb724 100644
--- a/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
@@ -65,6 +65,19 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase
@conn.columns_for_distinct("posts.id", [order])
end
+ def test_errors_for_bigint_fks_on_integer_pk_table
+ # table old_cars has primary key of integer
+
+ error = assert_raises(ActiveRecord::MismatchedForeignKey) do
+ @conn.add_reference :engines, :old_car
+ @conn.add_foreign_key :engines, :old_cars
+ end
+
+ assert_match "Column `old_car_id` on table `engines` has a type of `bigint(20)`", error.message
+ assert_not_nil error.cause
+ @conn.exec_query("ALTER TABLE engines DROP COLUMN old_car_id")
+ end
+
private
def with_example_table(definition = "id int auto_increment primary key, number int, data varchar(255)", &block)
diff --git a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
index d3c65f3d94..b787de8453 100644
--- a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
@@ -39,6 +39,10 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
expected = %(CREATE INDEX CONCURRENTLY "index_people_on_last_name" ON "people" ("last_name"))
assert_equal expected, add_index(:people, :last_name, algorithm: :concurrently)
+ expected = %(CREATE INDEX "index_people_on_last_name_and_first_name" ON "people" ("last_name" DESC, "first_name" ASC))
+ assert_equal expected, add_index(:people, [:last_name, :first_name], order: { last_name: :desc, first_name: :asc })
+ assert_equal expected, add_index(:people, ["last_name", :first_name], order: { last_name: :desc, "first_name" => :asc })
+
%w(gin gist hash btree).each do |type|
expected = %(CREATE INDEX "index_people_on_last_name" ON "people" USING #{type} ("last_name"))
assert_equal expected, add_index(:people, :last_name, using: type)
diff --git a/activerecord/test/cases/adapters/postgresql/legacy_migration_test.rb b/activerecord/test/cases/adapters/postgresql/legacy_migration_test.rb
new file mode 100644
index 0000000000..082fe95053
--- /dev/null
+++ b/activerecord/test/cases/adapters/postgresql/legacy_migration_test.rb
@@ -0,0 +1,54 @@
+require "cases/helper"
+
+class PostgresqlLegacyMigrationTest < ActiveRecord::PostgreSQLTestCase
+ class GenerateTableWithoutBigserial < ActiveRecord::Migration[5.0]
+ def change
+ create_table :legacy_integer_pk do |table|
+ table.string :foo
+ end
+
+ create_table :override_pk, id: :bigint do |table|
+ table.string :bar
+ end
+ end
+ end
+
+ def setup
+ super
+
+ @migration_verbose_old = ActiveRecord::Migration.verbose
+ ActiveRecord::Migration.verbose = false
+
+ migrations = [GenerateTableWithoutBigserial.new(nil, 1)]
+ ActiveRecord::Migrator.new(:up, migrations).migrate
+ end
+
+ def teardown
+ ActiveRecord::Migration.verbose = @migration_verbose_old
+
+ super
+ end
+
+ def test_create_table_uses_serial_as_pkey_by_default
+ col = column(:legacy_integer_pk, :id)
+ assert_equal "integer", sql_type_for(col)
+ assert col.serial?
+ end
+
+ def test_create_tables_respects_pk_column_type_override
+ col = column(:override_pk, :id)
+ assert_equal "bigint", sql_type_for(col)
+ end
+
+ private
+
+ def column(table_name, column_name)
+ ActiveRecord::Base.connection.
+ columns(table_name.to_s).
+ detect { |c| c.name == column_name.to_s }
+ end
+
+ def sql_type_for(col)
+ col && col.sql_type
+ end
+end
diff --git a/activerecord/test/cases/adapters/sqlite3/legacy_migration_test.rb b/activerecord/test/cases/adapters/sqlite3/legacy_migration_test.rb
new file mode 100644
index 0000000000..fcca8d66b5
--- /dev/null
+++ b/activerecord/test/cases/adapters/sqlite3/legacy_migration_test.rb
@@ -0,0 +1,59 @@
+require "cases/helper"
+
+class SqliteLegacyMigrationTest < ActiveRecord::SQLite3TestCase
+ self.use_transactional_tests = false
+
+ class GenerateTableWithoutBigint < ActiveRecord::Migration[5.0]
+ def change
+ create_table :legacy_integer_pk do |table|
+ table.string :foo
+ end
+
+ create_table :override_pk, id: :bigint do |table|
+ table.string :bar
+ end
+ end
+ end
+
+ def setup
+ super
+ @connection = ActiveRecord::Base.connection
+
+ @migration_verbose_old = ActiveRecord::Migration.verbose
+ ActiveRecord::Migration.verbose = false
+
+ migrations = [GenerateTableWithoutBigint.new(nil, 1)]
+
+ ActiveRecord::Migrator.new(:up, migrations).migrate
+ end
+
+ def teardown
+ ActiveRecord::Migration.verbose = @migration_verbose_old
+ @connection.drop_table("legacy_integer_pk")
+ @connection.drop_table("override_pk")
+ ActiveRecord::SchemaMigration.delete_all rescue nil
+ super
+ end
+
+ def test_create_table_uses_integer_as_pkey_by_default
+ col = column(:legacy_integer_pk, :id)
+ assert_equal "INTEGER", sql_type_for(col)
+ assert primary_key?(:legacy_integer_pk, "id"), "id is not primary key"
+ end
+
+ private
+
+ def column(table_name, column_name)
+ ActiveRecord::Base.connection
+ .columns(table_name.to_s)
+ .detect { |c| c.name == column_name.to_s }
+ end
+
+ def sql_type_for(col)
+ col && col.sql_type
+ end
+
+ def primary_key?(table_name, column)
+ ActiveRecord::Base.connection.execute("PRAGMA table_info(#{table_name})").find { |col| col["name"] == column }["pk"] == 1
+ end
+end
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index a3f82ed49d..77ee3ca2d7 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -1699,3 +1699,27 @@ class TestAutosaveAssociationWithTouch < ActiveRecord::TestCase
assert_nothing_raised { invoice.line_items.create(amount: 10) }
end
end
+
+class TestAutosaveAssociationOnAHasManyAssociationWithInverse < ActiveRecord::TestCase
+ class Post < ActiveRecord::Base
+ has_many :comments, inverse_of: :post
+ end
+
+ class Comment < ActiveRecord::Base
+ belongs_to :post, inverse_of: :comments
+
+ attr_accessor :post_comments_count
+ after_save do
+ self.post_comments_count = post.comments.count
+ end
+ end
+
+ def test_after_save_callback_with_autosave
+ post = Post.new(title: "Test", body: "...")
+ comment = post.comments.build(body: "...")
+ post.save!
+
+ assert_equal 1, post.comments.count
+ assert_equal 1, comment.post_comments_count
+ end
+end
diff --git a/activerecord/test/cases/comment_test.rb b/activerecord/test/cases/comment_test.rb
index 262ad319be..a625299e8d 100644
--- a/activerecord/test/cases/comment_test.rb
+++ b/activerecord/test/cases/comment_test.rb
@@ -2,7 +2,6 @@ require "cases/helper"
require "support/schema_dumping_helper"
if ActiveRecord::Base.connection.supports_comments?
-
class CommentTest < ActiveRecord::TestCase
include SchemaDumpingHelper
@@ -102,6 +101,7 @@ if ActiveRecord::Base.connection.supports_comments?
# Do all the stuff from other tests
@connection.add_column :commenteds, :rating, :integer, comment: "I am running out of imagination"
@connection.change_column :commenteds, :content, :string, comment: "Whoa, content describes itself!"
+ @connection.change_column :commenteds, :content, :string
@connection.change_column :commenteds, :obvious, :string, comment: nil
@connection.add_index :commenteds, :obvious, name: "idx_obvious", comment: "We need to see obvious comments"
@@ -135,5 +135,4 @@ if ActiveRecord::Base.connection.supports_comments?
assert_no_match %r[t\.string\s+"absent_comment", comment:\n], output
end
end
-
end
diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb
index fcaff38f82..6532efcf22 100644
--- a/activerecord/test/cases/defaults_test.rb
+++ b/activerecord/test/cases/defaults_test.rb
@@ -169,7 +169,7 @@ if current_adapter?(:Mysql2Adapter)
assert_nil record.non_null_text
assert_nil record.non_null_blob
- assert_raises(ActiveRecord::StatementInvalid) { klass.create }
+ assert_raises(ActiveRecord::NotNullViolation) { klass.create }
end
end
end
diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb
index bdb90eaa74..03f9c4a9ed 100644
--- a/activerecord/test/cases/migration/change_schema_test.rb
+++ b/activerecord/test/cases/migration/change_schema_test.rb
@@ -43,7 +43,7 @@ module ActiveRecord
t.column :foo, :string, null: false
end
- assert_raises(ActiveRecord::StatementInvalid) do
+ assert_raises(ActiveRecord::NotNullViolation) do
connection.execute "insert into testings (foo) values (NULL)"
end
end
@@ -233,7 +233,7 @@ module ActiveRecord
end
connection.add_column :testings, :bar, :string, null: false
- assert_raise(ActiveRecord::StatementInvalid) do
+ assert_raise(ActiveRecord::NotNullViolation) do
connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
end
end
@@ -244,12 +244,16 @@ module ActiveRecord
t.column :foo, :string
end
- con = connection
- connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}) values (1, 'hello')"
- assert_nothing_raised { connection.add_column :testings, :bar, :string, null: false, default: "default" }
+ quoted_id = connection.quote_column_name("id")
+ quoted_foo = connection.quote_column_name("foo")
+ quoted_bar = connection.quote_column_name("bar")
+ connection.execute("insert into testings (#{quoted_id}, #{quoted_foo}) values (1, 'hello')")
+ assert_nothing_raised do
+ connection.add_column :testings, :bar, :string, null: false, default: "default"
+ end
- assert_raises(ActiveRecord::StatementInvalid) do
- connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) values (2, 'hello', NULL)"
+ assert_raises(ActiveRecord::NotNullViolation) do
+ connection.execute("insert into testings (#{quoted_id}, #{quoted_foo}, #{quoted_bar}) values (2, 'hello', NULL)")
end
end
diff --git a/activerecord/test/cases/migration/change_table_test.rb b/activerecord/test/cases/migration/change_table_test.rb
index ec817a579b..8a4242cf1d 100644
--- a/activerecord/test/cases/migration/change_table_test.rb
+++ b/activerecord/test/cases/migration/change_table_test.rb
@@ -101,7 +101,12 @@ module ActiveRecord
def test_primary_key_creates_primary_key_column
with_change_table do |t|
- @connection.expect :add_column, nil, [:delete_me, :id, :primary_key, primary_key: true, first: true]
+ if current_adapter?(:Mysql2Adapter)
+ @connection.expect :add_column, nil, [:delete_me, :id, :primary_key, { first: true, auto_increment: true, limit: 8, primary_key: true }]
+ else
+ @connection.expect :add_column, nil, [:delete_me, :id, :primary_key, primary_key: true, first: true]
+ end
+
t.primary_key :id, first: true
end
end
diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb
index cab2069754..1921a4d7c2 100644
--- a/activerecord/test/cases/migration/foreign_key_test.rb
+++ b/activerecord/test/cases/migration/foreign_key_test.rb
@@ -76,7 +76,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
end
def test_add_foreign_key_with_non_standard_primary_key
- with_example_table @connection, "space_shuttles", "pk integer PRIMARY KEY" do
+ with_example_table @connection, "space_shuttles", "pk BIGINT PRIMARY KEY" do
@connection.add_foreign_key(:astronauts, :space_shuttles,
column: "rocket_id", primary_key: "pk", name: "custom_pk")
@@ -229,7 +229,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
create_table("cities") { |t| }
create_table("houses") do |t|
- t.column :city_id, :integer
+ t.column :city_id, :bigint
end
add_foreign_key :houses, :cities, column: "city_id"
@@ -261,7 +261,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
create_table(:schools)
create_table(:classes) do |t|
- t.column :school_id, :integer
+ t.column :school_id, :bigint
end
add_foreign_key :classes, :schools
end
diff --git a/activerecord/test/cases/migration/references_foreign_key_test.rb b/activerecord/test/cases/migration/references_foreign_key_test.rb
index 528811db49..4957ab8b3d 100644
--- a/activerecord/test/cases/migration/references_foreign_key_test.rb
+++ b/activerecord/test/cases/migration/references_foreign_key_test.rb
@@ -42,7 +42,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
test "options hash can be passed" do
@connection.change_table :testing_parents do |t|
- t.integer :other_id
+ t.bigint :other_id
t.index :other_id, unique: true
end
@connection.create_table :testings do |t|
@@ -92,7 +92,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
test "foreign keys accept options when changing the table" do
@connection.change_table :testing_parents do |t|
- t.integer :other_id
+ t.bigint :other_id
t.index :other_id, unique: true
end
@connection.create_table :testings
@@ -177,8 +177,8 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
test "multiple foreign keys can be added to the same table" do
@connection.create_table :testings do |t|
- t.integer :col_1
- t.integer :col_2
+ t.bigint :col_1
+ t.bigint :col_2
t.foreign_key :testing_parents, column: :col_1
t.foreign_key :testing_parents, column: :col_2
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index eaaf50d14f..b434f4a6b6 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -216,6 +216,43 @@ class PrimaryKeyWithNoConnectionTest < ActiveRecord::TestCase
end
end
+class PrimaryKeyWithAutoIncrementTest < ActiveRecord::TestCase
+ self.use_transactional_tests = false
+
+ class AutoIncrement < ActiveRecord::Base
+ end
+
+ def setup
+ @connection = ActiveRecord::Base.connection
+ end
+
+ def teardown
+ @connection.drop_table(:auto_increments, if_exists: true)
+ end
+
+ def test_primary_key_with_auto_increment
+ @connection.create_table(:auto_increments, id: :integer, auto_increment: true, force: true)
+ assert_auto_incremented
+ end
+
+ def test_primary_key_with_auto_increment_and_bigint
+ @connection.create_table(:auto_increments, id: :bigint, auto_increment: true, force: true)
+ assert_auto_incremented
+ end
+
+ private
+ def assert_auto_incremented
+ record1 = AutoIncrement.create!
+ assert_not_nil record1.id
+
+ record1.destroy
+
+ record2 = AutoIncrement.create!
+ assert_not_nil record2.id
+ assert_operator record2.id, :>, record1.id
+ end
+end
+
class PrimaryKeyAnyTypeTest < ActiveRecord::TestCase
include SchemaDumpingHelper
@@ -289,85 +326,69 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase
end
if current_adapter?(:Mysql2Adapter)
- class PrimaryKeyBigintNilDefaultTest < ActiveRecord::TestCase
+ class PrimaryKeyIntegerNilDefaultTest < ActiveRecord::TestCase
include SchemaDumpingHelper
self.use_transactional_tests = false
def setup
@connection = ActiveRecord::Base.connection
- @connection.create_table(:bigint_defaults, id: :bigint, default: nil, force: true)
+ @connection.create_table(:int_defaults, id: :integer, default: nil, force: true)
end
def teardown
- @connection.drop_table :bigint_defaults, if_exists: true
+ @connection.drop_table :int_defaults, if_exists: true
end
- test "primary key with bigint allows default override via nil" do
- column = @connection.columns(:bigint_defaults).find { |c| c.name == "id" }
- assert column.bigint?
+ test "primary key with integer allows default override via nil" do
+ column = @connection.columns(:int_defaults).find { |c| c.name == "id" }
+ assert_equal :integer, column.type
assert_not column.auto_increment?
end
- test "schema dump primary key with bigint default nil" do
- schema = dump_table_schema "bigint_defaults"
- assert_match %r{create_table "bigint_defaults", id: :bigint, default: nil}, schema
+ test "schema dump primary key with int default nil" do
+ schema = dump_table_schema "int_defaults"
+ assert_match %r{create_table "int_defaults", id: :integer, default: nil}, schema
end
end
end
-if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter)
- class PrimaryKeyBigSerialTest < ActiveRecord::TestCase
- include SchemaDumpingHelper
+class PrimaryKeyIntegerTest < ActiveRecord::TestCase
+ include SchemaDumpingHelper
- self.use_transactional_tests = false
+ self.use_transactional_tests = false
- class Widget < ActiveRecord::Base
- end
+ class Widget < ActiveRecord::Base
+ end
- setup do
- @connection = ActiveRecord::Base.connection
- if current_adapter?(:PostgreSQLAdapter)
- @connection.create_table(:widgets, id: :bigserial, force: true)
- else
- @connection.create_table(:widgets, id: :bigint, force: true)
- end
- end
+ setup do
+ @connection = ActiveRecord::Base.connection
+ @connection.create_table(:widgets, force: true)
+ end
- teardown do
- @connection.drop_table :widgets, if_exists: true
- Widget.reset_column_information
- end
+ teardown do
+ @connection.drop_table :widgets, if_exists: true
+ Widget.reset_column_information
+ end
- test "primary key column type with bigserial" do
- column_type = Widget.type_for_attribute(Widget.primary_key)
- assert_equal :integer, column_type.type
- assert_equal 8, column_type.limit
+ if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter)
+ test "schema dump primary key with bigserial" do
+ schema = dump_table_schema "widgets"
+ assert_match %r{create_table "widgets", force: :cascade}, schema
end
+ end
- test "primary key with bigserial are automatically numbered" do
- widget = Widget.create!
- assert_not_nil widget.id
- end
+ test "primary key column type" do
+ column_type = Widget.type_for_attribute(Widget.primary_key)
+ assert_equal :integer, column_type.type
- test "schema dump primary key with bigserial" do
- schema = dump_table_schema "widgets"
- if current_adapter?(:PostgreSQLAdapter)
- assert_match %r{create_table "widgets", id: :bigserial, force: :cascade}, schema
- else
- assert_match %r{create_table "widgets", id: :bigint, force: :cascade}, schema
- end
+ if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter)
+ assert_equal 8, column_type.limit
end
if current_adapter?(:Mysql2Adapter)
- test "primary key column type with options" do
- @connection.create_table(:widgets, id: :primary_key, limit: 8, unsigned: true, force: true)
- column = @connection.columns(:widgets).find { |c| c.name == "id" }
- assert column.auto_increment?
- assert_equal :integer, column.type
- assert_equal 8, column.limit
- assert column.unsigned?
- end
+ column = @connection.columns(:widgets).find { |c| c.name == "id" }
+ assert column.auto_increment?
end
end
end
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index 007f976f2e..97096e31e7 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -346,7 +346,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
create_table("dogs") do |t|
t.column :name, :string
- t.column :owner_id, :integer
+ t.column :owner_id, :bigint
t.index [:name]
t.foreign_key :dog_owners, column: "owner_id" if supports_foreign_keys?
end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index d889f46031..658591b6ec 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -54,7 +54,7 @@ ActiveRecord::Schema.define do
create_table :authors, force: true do |t|
t.string :name, null: false
- t.integer :author_address_id
+ t.bigint :author_address_id
t.integer :author_address_extra_id
t.string :organization_id
t.string :owned_essay_id
@@ -126,6 +126,9 @@ ActiveRecord::Schema.define do
t.timestamps null: false
end
+ create_table :old_cars, id: :integer, force: true do |t|
+ end
+
create_table :carriers, force: true
create_table :categories, force: true do |t|
@@ -303,7 +306,7 @@ ActiveRecord::Schema.define do
end
create_table :engines, force: true do |t|
- t.integer :car_id
+ t.bigint :car_id
end
create_table :entrants, force: true do |t|
@@ -1004,7 +1007,7 @@ ActiveRecord::Schema.define do
if supports_foreign_keys?
# fk_test_has_fk should be before fk_test_has_pk
create_table :fk_test_has_fk, force: true do |t|
- t.integer :fk_id, null: false
+ t.bigint :fk_id, null: false
end
create_table :fk_test_has_pk, force: true, primary_key: "pk_id" do |t|
diff --git a/railties/lib/rails/generators/rails/app/templates/config/puma.rb b/railties/lib/rails/generators/rails/app/templates/config/puma.rb
index 7ee948002e..1e19380dcb 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/puma.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/puma.rb
@@ -1,13 +1,13 @@
# Puma can serve each request in a thread from an internal thread pool.
-# The `threads` method setting takes two numbers a minimum and maximum.
+# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
-# and maximum, this matches the default thread size of Active Record.
+# and maximum; this matches the default thread size of Active Record.
#
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count
-# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
+# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch("PORT") { 3000 }
@@ -42,9 +42,9 @@ environment ENV.fetch("RAILS_ENV") { "development" }
# The code in the `on_worker_boot` will be called if you are using
# clustered mode by specifying a number of `workers`. After each worker
-# process is booted this block will be run, if you are using `preload_app!`
-# option you will want to use this block to reconnect to any threads
-# or connections that may have been created at application boot, Ruby
+# process is booted, this block will be run. If you are using the `preload_app!`
+# option, you will want to use this block to reconnect to any threads
+# or connections that may have been created at application boot, as Ruby
# cannot share connections between processes.
#
# on_worker_boot do