aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock126
-rw-r--r--activejob/lib/active_job/arguments.rb16
-rw-r--r--activejob/lib/active_job/enqueuing.rb10
-rw-r--r--activemodel/lib/active_model/errors.rb6
-rw-r--r--activemodel/lib/active_model/type/decimal.rb4
-rw-r--r--activemodel/test/cases/errors_test.rb10
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb17
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb6
-rw-r--r--activerecord/lib/active_record/transactions.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/create_unlogged_tables_test.rb74
-rw-r--r--activerecord/test/cases/adapters/postgresql/money_test.rb2
-rw-r--r--activerecord/test/cases/adapters/sqlite3/bind_parameter_test.rb20
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb24
-rw-r--r--activerecord/test/cases/hot_compatibility_test.rb2
-rw-r--r--activerecord/test/cases/numeric_data_test.rb34
-rw-r--r--guides/source/action_cable_overview.md6
-rw-r--r--guides/source/active_record_validations.md3
-rw-r--r--guides/source/configuring.md8
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md23
-rw-r--r--guides/source/development_dependencies_install.md364
-rw-r--r--guides/source/ruby_on_rails_guides_guidelines.md4
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb4
-rw-r--r--railties/test/application/bin_setup_test.rb2
-rw-r--r--railties/test/application/test_runner_test.rb24
31 files changed, 466 insertions, 382 deletions
diff --git a/Gemfile b/Gemfile
index fb15bf127e..9df706f9c2 100644
--- a/Gemfile
+++ b/Gemfile
@@ -104,8 +104,6 @@ group :test do
platforms :mri do
gem "stackprof"
gem "byebug"
- # FIXME: Remove this when thor 0.21 is release
- gem "thor", git: "https://github.com/erikhuda/thor.git", ref: "006832ea32480618791f89bb7d9e67b22fc814b9"
end
gem "benchmark-ips"
diff --git a/Gemfile.lock b/Gemfile.lock
index 1321436814..f4f3e430ba 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,11 +1,4 @@
GIT
- remote: https://github.com/erikhuda/thor.git
- revision: 006832ea32480618791f89bb7d9e67b22fc814b9
- ref: 006832ea32480618791f89bb7d9e67b22fc814b9
- specs:
- thor (0.20.0)
-
-GIT
remote: https://github.com/matthewd/rb-inotify.git
revision: 856730aad4b285969e8dd621e44808a7c5af4242
branch: close-handling
@@ -32,9 +25,9 @@ GIT
GIT
remote: https://github.com/rails/webpacker.git
- revision: 48d9fd52c3e9637dbb21e551b48c84c0f2dbb2ed
+ revision: bb132d591da35095e3246082cba3d693f847e0b5
specs:
- webpacker (4.0.0.pre.pre.2)
+ webpacker (4.0.0.pre.3)
activesupport (>= 4.2)
rack-proxy (>= 0.6.1)
railties (>= 4.2)
@@ -105,16 +98,16 @@ PATH
GEM
remote: https://rubygems.org/
specs:
- activerecord-jdbc-adapter (52.0-java)
+ activerecord-jdbc-adapter (52.1-java)
activerecord (~> 5.2.0)
- activerecord-jdbcmysql-adapter (52.0-java)
- activerecord-jdbc-adapter (= 52.0)
+ activerecord-jdbcmysql-adapter (52.1-java)
+ activerecord-jdbc-adapter (= 52.1)
jdbc-mysql (~> 5.1.36)
- activerecord-jdbcpostgresql-adapter (52.0-java)
- activerecord-jdbc-adapter (= 52.0)
+ activerecord-jdbcpostgresql-adapter (52.1-java)
+ activerecord-jdbc-adapter (= 52.1)
jdbc-postgres (>= 9.4, < 43)
- activerecord-jdbcsqlite3-adapter (52.0-java)
- activerecord-jdbc-adapter (= 52.0)
+ activerecord-jdbcsqlite3-adapter (52.1-java)
+ activerecord-jdbc-adapter (= 52.1)
jdbc-sqlite3 (~> 3.8, < 3.30)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
@@ -123,17 +116,17 @@ GEM
io-like (~> 0.3.0)
ast (2.4.0)
aws-eventstream (1.0.1)
- aws-partitions (1.102.0)
- aws-sdk-core (3.25.0)
+ aws-partitions (1.111.0)
+ aws-sdk-core (3.37.0)
aws-eventstream (~> 1.0)
aws-partitions (~> 1.0)
aws-sigv4 (~> 1.0)
jmespath (~> 1.0)
- aws-sdk-kms (1.7.0)
- aws-sdk-core (~> 3)
+ aws-sdk-kms (1.11.0)
+ aws-sdk-core (~> 3, >= 3.26.0)
aws-sigv4 (~> 1.0)
- aws-sdk-s3 (1.17.1)
- aws-sdk-core (~> 3, >= 3.21.2)
+ aws-sdk-s3 (1.23.1)
+ aws-sdk-core (~> 3, >= 3.26.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.0)
aws-sigv4 (1.0.3)
@@ -173,38 +166,38 @@ GEM
childprocess
faraday
selenium-webdriver
- bootsnap (1.3.1)
+ bootsnap (1.3.2)
msgpack (~> 1.0)
- bootsnap (1.3.1-java)
+ bootsnap (1.3.2-java)
msgpack (~> 1.0)
builder (3.2.3)
bunny (2.9.2)
amq-protocol (~> 2.3.0)
byebug (10.0.2)
- capybara (3.7.1)
+ capybara (3.10.1)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
- xpath (~> 3.1)
+ regexp_parser (~> 1.2)
+ xpath (~> 3.2)
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
- chromedriver-helper (2.0.0)
+ chromedriver-helper (2.1.0)
archive-zip (~> 0.10)
nokogiri (~> 1.8)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
- concurrent-ruby (1.0.5)
- concurrent-ruby (1.0.5-java)
+ concurrent-ruby (1.1.3)
connection_pool (2.2.2)
cookiejar (0.3.3)
crass (1.0.4)
curses (1.0.2)
daemons (1.2.6)
- dalli (2.7.8)
+ dalli (2.7.9)
dante (0.2.0)
declarative (0.0.10)
declarative-option (0.1.0)
@@ -228,7 +221,7 @@ GEM
event_emitter (0.2.6)
eventmachine (1.2.7)
execjs (2.7.0)
- faraday (0.15.2)
+ faraday (0.15.3)
multipart-post (>= 1.2, < 3)
faraday_middleware (0.12.2)
faraday (>= 0.7.4, < 1.0)
@@ -252,39 +245,39 @@ GEM
raabro (~> 1.1)
globalid (0.4.1)
activesupport (>= 4.2.0)
- google-api-client (0.23.8)
+ google-api-client (0.25.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0)
httpclient (>= 2.8.1, < 3.0)
mime-types (~> 3.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
- signet (~> 0.9)
- google-cloud-core (1.2.3)
+ signet (~> 0.10)
+ google-cloud-core (1.2.7)
google-cloud-env (~> 1.0)
- google-cloud-env (1.0.2)
+ google-cloud-env (1.0.5)
faraday (~> 0.11)
- google-cloud-storage (1.13.1)
+ google-cloud-storage (1.15.0)
digest-crc (~> 0.4)
google-api-client (~> 0.23)
google-cloud-core (~> 1.2)
googleauth (~> 0.6.2)
- googleauth (0.6.6)
+ googleauth (0.6.7)
faraday (~> 0.12)
jwt (>= 1.4, < 3.0)
- memoist (~> 0.12)
+ memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.7)
- hiredis (0.6.1)
- hiredis (0.6.1-java)
+ hiredis (0.6.3)
+ hiredis (0.6.3-java)
http_parser.rb (0.6.0)
httpclient (2.8.3)
- i18n (1.1.0)
+ i18n (1.1.1)
concurrent-ruby (~> 1.0)
- image_processing (1.6.0)
+ image_processing (1.7.1)
mini_magick (~> 4.0)
- ruby-vips (>= 2.0.11, < 3)
+ ruby-vips (>= 2.0.13, < 3)
io-like (0.3.0)
jaro_winkler (1.5.1)
jaro_winkler (1.5.1-java)
@@ -303,7 +296,7 @@ GEM
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
- loofah (2.2.2)
+ loofah (2.2.3)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
@@ -311,7 +304,7 @@ GEM
marcel (0.3.3)
mimemagic (~> 0.3.2)
memoist (0.16.0)
- method_source (0.9.0)
+ method_source (0.9.1)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2018.0812)
@@ -334,7 +327,7 @@ GEM
msgpack (1.2.4-x86-mingw32)
multi_json (1.13.1)
multipart-post (2.0.0)
- mustache (1.0.5)
+ mustache (1.1.0)
mustermann (1.0.3)
mysql2 (0.5.2)
mysql2 (0.5.2-x64-mingw32)
@@ -350,14 +343,14 @@ GEM
mini_portile2 (~> 2.3.0)
os (1.0.0)
parallel (1.12.1)
- parser (2.5.1.2)
+ parser (2.5.3.0)
ast (~> 2.4.0)
path_expander (1.0.3)
pg (1.1.3)
pg (1.1.3-x64-mingw32)
pg (1.1.3-x86-mingw32)
powerpack (0.1.2)
- psych (3.0.2)
+ psych (3.0.3)
public_suffix (3.0.3)
puma (3.12.0)
puma (3.12.0-java)
@@ -367,10 +360,10 @@ GEM
thor
raabro (1.1.6)
racc (1.4.14)
- rack (2.0.5)
+ rack (2.0.6)
rack-cache (1.8.0)
rack (>= 0.4)
- rack-protection (2.0.3)
+ rack-protection (2.0.4)
rack
rack-proxy (0.6.5)
rack
@@ -386,9 +379,10 @@ GEM
rb-fsevent (0.10.3)
rdoc (6.0.4)
redcarpet (3.2.3)
- redis (4.0.2)
+ redis (4.0.3)
redis-namespace (1.6.0)
redis (>= 3.0.4)
+ regexp_parser (1.2.0)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
@@ -405,14 +399,14 @@ GEM
resque (~> 1.26)
rufus-scheduler (~> 3.2)
retriable (3.1.2)
- rubocop (0.58.2)
+ rubocop (0.60.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.5, != 2.5.1.1)
powerpack (~> 0.1)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
- unicode-display_width (~> 1.0, >= 1.0.1)
+ unicode-display_width (~> 1.4.0)
ruby-progressbar (1.10.0)
ruby-vips (2.0.13)
ffi (~> 1.9)
@@ -420,7 +414,7 @@ GEM
rubyzip (1.2.2)
rufus-scheduler (3.5.2)
fugit (~> 1.1, >= 1.1.5)
- sass (3.5.7)
+ sass (3.7.2)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
@@ -433,26 +427,26 @@ GEM
tilt (>= 1.1, < 3)
sdoc (1.0.0)
rdoc (>= 5.0)
- selenium-webdriver (3.14.0)
+ selenium-webdriver (3.141.0)
childprocess (~> 0.5)
- rubyzip (~> 1.2)
- sequel (5.12.0)
+ rubyzip (~> 1.2, >= 1.2.2)
+ sequel (5.14.0)
serverengine (2.0.7)
sigdump (~> 0.2.2)
- sidekiq (5.2.1)
+ sidekiq (5.2.3)
connection_pool (~> 2.2, >= 2.2.2)
rack-protection (>= 1.5.0)
redis (>= 3.3.5, < 5)
sigdump (0.2.4)
- signet (0.9.1)
+ signet (0.11.0)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
- sinatra (2.0.3)
+ sinatra (2.0.4)
mustermann (~> 1.0)
rack (~> 2.0)
- rack-protection (= 2.0.3)
+ rack-protection (= 2.0.4)
tilt (~> 2.0)
sneakers (2.7.0)
bunny (~> 2.9.2)
@@ -477,6 +471,7 @@ GEM
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
+ thor (0.20.3)
thread_safe (0.3.6)
thread_safe (0.3.6-java)
tilt (2.0.8)
@@ -485,10 +480,10 @@ GEM
turbolinks-source (5.2.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
- tzinfo-data (1.2018.5)
+ tzinfo-data (1.2018.7)
tzinfo (>= 1.0.0)
uber (0.1.0)
- uglifier (4.1.18)
+ uglifier (4.1.19)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.4.0)
useragent (0.16.10)
@@ -504,7 +499,7 @@ GEM
websocket-driver (0.7.0-java)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
- xpath (3.1.0)
+ xpath (3.2.0)
nokogiri (~> 1.8)
PLATFORMS
@@ -569,7 +564,6 @@ DEPENDENCIES
sqlite3 (~> 1.3.6)
stackprof
sucker_punch
- thor!
turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
@@ -579,4 +573,4 @@ DEPENDENCIES
websocket-client-simple!
BUNDLED WITH
- 1.16.6
+ 1.17.1
diff --git a/activejob/lib/active_job/arguments.rb b/activejob/lib/active_job/arguments.rb
index 31347194d2..ffc57dae84 100644
--- a/activejob/lib/active_job/arguments.rb
+++ b/activejob/lib/active_job/arguments.rb
@@ -14,18 +14,18 @@ module ActiveJob
end
# Raised when an unsupported argument type is set as a job argument. We
- # currently support NilClass, Integer, Float, String, TrueClass, FalseClass,
- # BigDecimal, and objects that can be represented as GlobalIDs (ex: Active Record).
+ # currently support String, Integer, Float, NilClass, TrueClass, FalseClass,
+ # BigDecimal, Symbol, Date, Time, DateTime, ActiveSupport::TimeWithZone,
+ # ActiveSupport::Duration, Hash, ActiveSupport::HashWithIndifferentAccess,
+ # Array or GlobalID::Identification instances, although this can be extended
+ # by adding custom serializers.
# Raised if you set the key for a Hash something else than a string or
# a symbol. Also raised when trying to serialize an object which can't be
- # identified with a Global ID - such as an unpersisted Active Record model.
+ # identified with a GlobalID - such as an unpersisted Active Record model.
class SerializationError < ArgumentError; end
module Arguments
extend self
- # :nodoc:
- PERMITTED_TYPES = [ NilClass, String, Integer, Float, BigDecimal, TrueClass, FalseClass ]
-
# Serializes a set of arguments. Intrinsic types that can safely be
# serialized without mutation are returned as-is. Arrays/Hashes are
# serialized element by element. All other types are serialized using
@@ -47,6 +47,8 @@ module ActiveJob
private
# :nodoc:
+ PERMITTED_TYPES = [ NilClass, String, Integer, Float, BigDecimal, TrueClass, FalseClass ]
+ # :nodoc:
GLOBALID_KEY = "_aj_globalid"
# :nodoc:
SYMBOL_KEYS_KEY = "_aj_symbol_keys"
@@ -62,7 +64,7 @@ module ActiveJob
OBJECT_SERIALIZER_KEY, OBJECT_SERIALIZER_KEY.to_sym,
WITH_INDIFFERENT_ACCESS_KEY, WITH_INDIFFERENT_ACCESS_KEY.to_sym,
]
- private_constant :RESERVED_KEYS
+ private_constant :PERMITTED_TYPES, :RESERVED_KEYS, :GLOBALID_KEY, :SYMBOL_KEYS_KEY, :WITH_INDIFFERENT_ACCESS_KEY
def serialize_argument(argument)
case argument
diff --git a/activejob/lib/active_job/enqueuing.rb b/activejob/lib/active_job/enqueuing.rb
index 53cb98fc71..b5b9f23c00 100644
--- a/activejob/lib/active_job/enqueuing.rb
+++ b/activejob/lib/active_job/enqueuing.rb
@@ -9,10 +9,12 @@ module ActiveJob
# Includes the +perform_later+ method for job initialization.
module ClassMethods
- # Push a job onto the queue. The arguments must be legal JSON types
- # (+string+, +int+, +float+, +nil+, +true+, +false+, +hash+ or +array+) or
- # GlobalID::Identification instances. Arbitrary Ruby objects
- # are not supported.
+ # Push a job onto the queue. By default the arguments must be either String,
+ # Integer, Float, NilClass, TrueClass, FalseClass, BigDecimal, Symbol, Date,
+ # Time, DateTime, ActiveSupport::TimeWithZone, ActiveSupport::Duration,
+ # Hash, ActiveSupport::HashWithIndifferentAccess, Array or
+ # GlobalID::Identification instances, although this can be extended by adding
+ # custom serializers.
#
# Returns an instance of the job class queued with arguments available in
# Job#arguments.
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index af94d52d45..9de6b609a3 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -327,11 +327,11 @@ module ActiveModel
# person.errors.added? :name, :too_long # => false
# person.errors.added? :name, "is too long" # => false
def added?(attribute, message = :invalid, options = {})
+ message = message.call if message.respond_to?(:call)
+
if message.is_a? Symbol
- self.details[attribute.to_sym].map { |e| e[:error] }.include? message
+ details[attribute.to_sym].include? normalize_detail(message, options)
else
- message = message.call if message.respond_to?(:call)
- message = normalize_message(attribute, message, options)
self[attribute].include? message
end
end
diff --git a/activemodel/lib/active_model/type/decimal.rb b/activemodel/lib/active_model/type/decimal.rb
index e8ee18c00e..b37dad1c41 100644
--- a/activemodel/lib/active_model/type/decimal.rb
+++ b/activemodel/lib/active_model/type/decimal.rb
@@ -12,6 +12,10 @@ module ActiveModel
:decimal
end
+ def serialize(value)
+ cast(value)
+ end
+
def type_cast_for_schema(value)
value.to_s.inspect
end
diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb
index 41ff6443fe..185b5a24ae 100644
--- a/activemodel/test/cases/errors_test.rb
+++ b/activemodel/test/cases/errors_test.rb
@@ -228,6 +228,16 @@ class ErrorsTest < ActiveModel::TestCase
assert_not person.errors.added?(:name)
end
+ test "added? returns false when checking for an error with an incorrect or missing option" do
+ person = Person.new
+ person.errors.add :name, :too_long, count: 25
+
+ assert person.errors.added? :name, :too_long, count: 25
+ assert_not person.errors.added? :name, :too_long, count: 24
+ assert_not person.errors.added? :name, :too_long
+ assert_not person.errors.added? :name, "is too long"
+ end
+
test "added? returns false when checking for an error by symbol and a different error with same message is present" do
I18n.backend.store_translations("en", errors: { attributes: { name: { wrong: "is wrong", used: "is wrong" } } })
person = Person.new
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb
index 19ff780192..2cb0a2a4df 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_creation.rb
@@ -39,7 +39,7 @@ module ActiveRecord
end
def visit_TableDefinition(o)
- create_sql = +"CREATE#{' TEMPORARY' if o.temporary} TABLE "
+ create_sql = +"CREATE#{table_modifier_in_create(o)} TABLE "
create_sql << "IF NOT EXISTS " if o.if_not_exists
create_sql << "#{quote_table_name(o.name)} "
@@ -121,6 +121,11 @@ module ActiveRecord
sql
end
+ # Returns any SQL string to go between CREATE and TABLE. May be nil.
+ def table_modifier_in_create(o)
+ " TEMPORARY" if o.temporary
+ end
+
def foreign_key_in_create(from_table, to_table, options)
options = foreign_key_options(from_table, to_table, options)
accept ForeignKeyDefinition.new(from_table, to_table, options)
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 ca99a2d983..db489143af 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/deprecation"
+
module ActiveRecord
module ConnectionAdapters #:nodoc:
# Abstract representation of an index definition on a table. Instances of
@@ -256,10 +258,19 @@ module ActiveRecord
class TableDefinition
include ColumnMethods
- attr_accessor :indexes
- attr_reader :name, :temporary, :if_not_exists, :options, :as, :foreign_keys, :comment
+ attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
+ attr_writer :indexes
+ deprecate :indexes=
- def initialize(name, temporary = false, if_not_exists = false, options = nil, as = nil, comment: nil)
+ def initialize(
+ name,
+ temporary: false,
+ if_not_exists: false,
+ options: nil,
+ as: nil,
+ comment: nil,
+ **
+ )
@columns_hash = {}
@indexes = []
@foreign_keys = []
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 295ad89f7c..38cfc3a241 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -290,8 +290,8 @@ module ActiveRecord
# SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id
#
# See also TableDefinition#column for details on how to create columns.
- def create_table(table_name, comment: nil, **options)
- td = create_table_definition table_name, options[:temporary], options[:if_not_exists], options[:options], options[:as], comment: comment
+ def create_table(table_name, **options)
+ td = create_table_definition(table_name, options)
if options[:id] != false && !options[:as]
pk = options.fetch(:primary_key) do
@@ -320,7 +320,9 @@ module ActiveRecord
end
if supports_comments? && !supports_comments_in_create?
- change_table_comment(table_name, comment) if comment.present?
+ if table_comment = options[:comment].presence
+ change_table_comment(table_name, table_comment)
+ end
td.columns.each do |column|
change_column_comment(table_name, column.name, column.comment) if column.comment.present?
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
index e75202b0be..0895d06356 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb
@@ -93,11 +93,11 @@ module ActiveRecord
elsif value.hex?
"X'#{value}'"
end
- when Float
- if value.infinite? || value.nan?
- "'#{value}'"
- else
+ when Numeric
+ if value.finite?
super
+ else
+ "'#{value}'"
end
when OID::Array::Data
_quote(encode_array(value))
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb
index 8e381a92cf..ceb8b40bd9 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation.rb
@@ -23,6 +23,17 @@ module ActiveRecord
end
super
end
+
+ # Returns any SQL string to go between CREATE and TABLE. May be nil.
+ def table_modifier_in_create(o)
+ # A table cannot be both TEMPORARY and UNLOGGED, since all TEMPORARY
+ # tables are already UNLOGGED.
+ if o.temporary
+ " TEMPORARY"
+ elsif o.unlogged
+ " UNLOGGED"
+ end
+ end
end
end
end
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 206b855a18..dc4a0bb26e 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb
@@ -175,6 +175,13 @@ module ActiveRecord
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
include ColumnMethods
+ attr_reader :unlogged
+
+ def initialize(*)
+ super
+ @unlogged = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables
+ end
+
private
def integer_like_primary_key_type(type, options)
if type == :bigint || options[:limit] == 8
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index a11a786ec7..f701292be3 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -85,6 +85,18 @@ module ActiveRecord
class PostgreSQLAdapter < AbstractAdapter
ADAPTER_NAME = "PostgreSQL"
+ ##
+ # :singleton-method:
+ # PostgreSQL allows the creation of "unlogged" tables, which do not record
+ # data in the PostgreSQL Write-Ahead Log. This can make the tables faster,
+ # bug significantly increases the risk of data loss if the database
+ # crashes. As a result, this should not be used in production
+ # environments. If you would like all created tables to be unlogged you
+ # can add the following line to your test.rb file:
+ #
+ # ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables = true
+ class_attribute :create_unlogged_tables, default: false
+
NATIVE_DATABASE_TYPES = {
primary_key: "bigserial primary key",
string: { name: "character varying" },
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index e0355a316b..3312c3de01 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -396,6 +396,12 @@ module ActiveRecord
end
private
+ # See https://www.sqlite.org/limits.html,
+ # the default value is 999 when not configured.
+ def bind_params_length
+ 999
+ end
+
def check_version
if sqlite_version < "3.8.0"
raise "Your version of SQLite (#{sqlite_version}) is too old. Active Record supports SQLite >= 3.8."
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index c5d5fca672..fe3842b905 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -375,10 +375,6 @@ module ActiveRecord
raise ActiveRecord::Rollback unless status
end
status
- ensure
- if @transaction_state && @transaction_state.committed?
- clear_transaction_record_state
- end
end
private
diff --git a/activerecord/test/cases/adapters/postgresql/create_unlogged_tables_test.rb b/activerecord/test/cases/adapters/postgresql/create_unlogged_tables_test.rb
new file mode 100644
index 0000000000..a02bae1453
--- /dev/null
+++ b/activerecord/test/cases/adapters/postgresql/create_unlogged_tables_test.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require "cases/helper"
+require "support/schema_dumping_helper"
+
+class UnloggedTablesTest < ActiveRecord::PostgreSQLTestCase
+ include SchemaDumpingHelper
+
+ TABLE_NAME = "things"
+ LOGGED_FIELD = "relpersistence"
+ LOGGED_QUERY = "SELECT #{LOGGED_FIELD} FROM pg_class WHERE relname = '#{TABLE_NAME}'"
+ LOGGED = "p"
+ UNLOGGED = "u"
+ TEMPORARY = "t"
+
+ class Thing < ActiveRecord::Base
+ self.table_name = TABLE_NAME
+ end
+
+ def setup
+ @connection = ActiveRecord::Base.connection
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables = false
+ end
+
+ teardown do
+ @connection.drop_table TABLE_NAME, if_exists: true
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables = false
+ end
+
+ def test_logged_by_default
+ @connection.create_table(TABLE_NAME) do |t|
+ end
+ assert_equal @connection.execute(LOGGED_QUERY).first[LOGGED_FIELD], LOGGED
+ end
+
+ def test_unlogged_in_test_environment_when_unlogged_setting_enabled
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables = true
+
+ @connection.create_table(TABLE_NAME) do |t|
+ end
+ assert_equal @connection.execute(LOGGED_QUERY).first[LOGGED_FIELD], UNLOGGED
+ end
+
+ def test_not_included_in_schema_dump
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables = true
+
+ @connection.create_table(TABLE_NAME) do |t|
+ end
+ assert_no_match(/unlogged/i, dump_table_schema(TABLE_NAME))
+ end
+
+ def test_not_changed_in_change_table
+ @connection.create_table(TABLE_NAME) do |t|
+ end
+
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables = true
+
+ @connection.change_table(TABLE_NAME) do |t|
+ t.column :name, :string
+ end
+ assert_equal @connection.execute(LOGGED_QUERY).first[LOGGED_FIELD], LOGGED
+ end
+
+ def test_gracefully_handles_temporary_tables
+ @connection.create_table(TABLE_NAME, temporary: true) do |t|
+ end
+
+ # Temporary tables are already unlogged, though this query results in a
+ # different result ("t" vs. "u"). This test is really just checking that we
+ # didn't try to run `CREATE TEMPORARY UNLOGGED TABLE`, which would result in
+ # a PostgreSQL error.
+ assert_equal @connection.execute(LOGGED_QUERY).first[LOGGED_FIELD], TEMPORARY
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/money_test.rb b/activerecord/test/cases/adapters/postgresql/money_test.rb
index 75e5aaed53..1aa0348879 100644
--- a/activerecord/test/cases/adapters/postgresql/money_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/money_test.rb
@@ -37,7 +37,7 @@ class PostgresqlMoneyTest < ActiveRecord::PostgreSQLTestCase
def test_default
assert_equal BigDecimal("150.55"), PostgresqlMoney.column_defaults["depth"]
assert_equal BigDecimal("150.55"), PostgresqlMoney.new.depth
- assert_equal "$150.55", PostgresqlMoney.new.depth_before_type_cast
+ assert_equal "150.55", PostgresqlMoney.new.depth_before_type_cast
end
def test_money_values
diff --git a/activerecord/test/cases/adapters/sqlite3/bind_parameter_test.rb b/activerecord/test/cases/adapters/sqlite3/bind_parameter_test.rb
new file mode 100644
index 0000000000..93a7dafebd
--- /dev/null
+++ b/activerecord/test/cases/adapters/sqlite3/bind_parameter_test.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require "cases/helper"
+require "models/topic"
+
+module ActiveRecord
+ module ConnectionAdapters
+ class SQLite3Adapter
+ class BindParameterTest < ActiveRecord::SQLite3TestCase
+ def test_too_many_binds
+ topics = Topic.where(id: (1..999).to_a << 2**63)
+ assert_equal Topic.count, topics.count
+
+ topics = Topic.where.not(id: (1..999).to_a << 2**63)
+ assert_equal 0, topics.count
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
index a520fb1303..0e4ea62113 100644
--- a/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handlers_multi_db_test.rb
@@ -127,6 +127,9 @@ module ActiveRecord
ActiveRecord::Base.connected_to(database: { writing: "postgres://localhost/bar" }) do
handler = ActiveRecord::Base.connection_handler
assert_equal handler, ActiveRecord::Base.connection_handlers[:writing]
+
+ assert_not_nil pool = handler.retrieve_connection_pool("primary")
+ assert_equal({ adapter: "postgresql", database: "bar", host: "localhost" }, pool.spec.config)
end
ensure
ActiveRecord::Base.establish_connection(:arunit)
@@ -136,11 +139,14 @@ module ActiveRecord
def test_switching_connections_with_database_config_hash
previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "default_env"
- config = { "adapter" => "sqlite3", "database" => "db/readonly.sqlite3" }
+ config = { adapter: "sqlite3", database: "db/readonly.sqlite3" }
ActiveRecord::Base.connected_to(database: { writing: config }) do
handler = ActiveRecord::Base.connection_handler
assert_equal handler, ActiveRecord::Base.connection_handlers[:writing]
+
+ assert_not_nil pool = handler.retrieve_connection_pool("primary")
+ assert_equal(config, pool.spec.config)
end
ensure
ActiveRecord::Base.establish_connection(:arunit)
@@ -150,11 +156,23 @@ module ActiveRecord
def test_switching_connections_with_database_symbol
previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "default_env"
- ActiveRecord::Base.connected_to(database: :arunit2) do
+ config = {
+ "default_env" => {
+ "readonly" => { adapter: "sqlite3", database: "db/readonly.sqlite3" },
+ "primary" => { adapter: "sqlite3", database: "db/primary.sqlite3" }
+ }
+ }
+ @prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
+
+ ActiveRecord::Base.connected_to(database: :readonly) do
handler = ActiveRecord::Base.connection_handler
- assert_equal handler, ActiveRecord::Base.connection_handlers[:arunit2]
+ assert_equal handler, ActiveRecord::Base.connection_handlers[:readonly]
+
+ assert_not_nil pool = handler.retrieve_connection_pool("primary")
+ assert_equal(config["default_env"]["readonly"], pool.spec.config)
end
ensure
+ ActiveRecord::Base.configurations = @prev_configs
ActiveRecord::Base.establish_connection(:arunit)
ENV["RAILS_ENV"] = previous_env
end
diff --git a/activerecord/test/cases/hot_compatibility_test.rb b/activerecord/test/cases/hot_compatibility_test.rb
index e7778af55b..7b388ebc5e 100644
--- a/activerecord/test/cases/hot_compatibility_test.rb
+++ b/activerecord/test/cases/hot_compatibility_test.rb
@@ -56,7 +56,7 @@ class HotCompatibilityTest < ActiveRecord::TestCase
assert_equal "bar", record.foo
end
- if current_adapter?(:PostgreSQLAdapter)
+ if current_adapter?(:PostgreSQLAdapter) && ActiveRecord::Base.connection.prepared_statements
test "cleans up after prepared statement failure in a transaction" do
with_two_connections do |original_connection, ddl_connection|
record = @klass.create! bar: "bar"
diff --git a/activerecord/test/cases/numeric_data_test.rb b/activerecord/test/cases/numeric_data_test.rb
index 14db63890e..079e664ee4 100644
--- a/activerecord/test/cases/numeric_data_test.rb
+++ b/activerecord/test/cases/numeric_data_test.rb
@@ -24,8 +24,10 @@ class NumericDataTest < ActiveRecord::TestCase
)
assert m.save
- m1 = NumericData.find(m.id)
- assert_not_nil m1
+ m1 = NumericData.find_by(
+ bank_balance: 1586.43,
+ big_bank_balance: BigDecimal("1000234000567.95")
+ )
assert_kind_of Integer, m1.world_population
assert_equal 2**62, m1.world_population
@@ -49,8 +51,10 @@ class NumericDataTest < ActiveRecord::TestCase
)
assert m.save
- m1 = NumericData.find(m.id)
- assert_not_nil m1
+ m1 = NumericData.find_by(
+ bank_balance: 1586.43122334,
+ big_bank_balance: BigDecimal("234000567.952344")
+ )
assert_kind_of Integer, m1.world_population
assert_equal 2**62, m1.world_population
@@ -64,4 +68,26 @@ class NumericDataTest < ActiveRecord::TestCase
assert_kind_of BigDecimal, m1.big_bank_balance
assert_equal BigDecimal("234000567.95"), m1.big_bank_balance
end
+
+ if current_adapter?(:PostgreSQLAdapter)
+ def test_numeric_fields_with_nan
+ m = NumericData.new(
+ bank_balance: BigDecimal("NaN"),
+ big_bank_balance: BigDecimal("NaN"),
+ world_population: 2**62,
+ my_house_population: 3
+ )
+ assert_predicate m.bank_balance, :nan?
+ assert_predicate m.big_bank_balance, :nan?
+ assert m.save
+
+ m1 = NumericData.find_by(
+ bank_balance: BigDecimal("NaN"),
+ big_bank_balance: BigDecimal("NaN")
+ )
+
+ assert_predicate m1.bank_balance, :nan?
+ assert_predicate m1.big_bank_balance, :nan?
+ end
+ end
end
diff --git a/guides/source/action_cable_overview.md b/guides/source/action_cable_overview.md
index e6c0ae31a8..2f602c3e0a 100644
--- a/guides/source/action_cable_overview.md
+++ b/guides/source/action_cable_overview.md
@@ -242,9 +242,9 @@ WebNotificationsChannel.broadcast_to(
```
The `WebNotificationsChannel.broadcast_to` call places a message in the current
-subscription adapter (by default `redis` for production and `async` for development and
-test environments)'s pubsub queue under a separate broadcasting name for each user.
-For a user with an ID of 1, the broadcasting name would be `web_notifications:1`.
+subscription adapter's pubsub queue under a separate broadcasting name for each user.
+The default pubsub queue for Action Cable is `redis` in production and `async` in development and
+test environments. For a user with an ID of 1, the broadcasting name would be `web_notifications:1`.
The channel has been instructed to stream everything that arrives at
`web_notifications:1` directly to the client by invoking the `received`
diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md
index c98f24d786..0fda7c5cfd 100644
--- a/guides/source/active_record_validations.md
+++ b/guides/source/active_record_validations.md
@@ -538,7 +538,8 @@ end
If you want to be sure that an association is present, you'll need to test
whether the associated object itself is present, and not the foreign key used
-to map the association.
+to map the association. This way, it is not only checked that the foreign key
+is not empty but also that the referenced object exists.
```ruby
class LineItem < ApplicationRecord
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index d03943ba4a..706964090e 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -379,6 +379,14 @@ The MySQL adapter adds one additional configuration option:
* `ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans` controls whether Active Record will consider all `tinyint(1)` columns as booleans. Defaults to `true`.
+The PostgreSQL adapter adds one additional configuration option:
+
+* `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables`
+ controls whether database tables created should be "unlogged," which can speed
+ up performance but adds a risk of data loss if the database crashes. It is
+ highly recommended that you do not enable this in a production environment.
+ Defaults to `false` in all environments.
+
The SQLite3Adapter adapter adds one additional configuration option:
* `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer`
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index ed47a0de0f..709a5146e9 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -324,6 +324,26 @@ $ cd actionmailer
$ bundle exec rake test
```
+#### For a Specific Directory
+
+If you want to run the tests located in a specific directory use the `TEST_DIR`
+environment variable. For example, this will run the tests in the
+`railties/test/generators` directory only:
+
+```bash
+$ cd railties
+$ TEST_DIR=generators bundle exec rake test
+```
+
+#### For a Specific File
+
+You can run the tests for a particular file by using:
+
+```bash
+$ cd actionpack
+$ bundle exec ruby -w -Itest test/template/form_helper_test.rb
+```
+
#### Running a Single Test
You can run a single test through ruby. For instance:
@@ -333,8 +353,7 @@ $ cd actionmailer
$ bundle exec ruby -w -Itest test/mail_layout_test.rb -n test_explicit_class_layout
```
-The `-n` option allows you to run a single method instead of the whole
-file.
+The `-n` option allows you to run a single method instead of the whole file.
#### Running tests with a specific seed
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index 07538a1cb7..d52946be08 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -8,8 +8,6 @@ This guide covers how to setup an environment for Ruby on Rails core development
After reading this guide, you will know:
* How to set up your machine for Rails development
-* How to run specific groups of unit tests from the Rails test suite
-* How the Active Record portion of the Rails test suite operates
--------------------------------------------------------------------------------
@@ -43,195 +41,131 @@ $ git clone https://github.com/rails/rails.git
$ cd rails
```
-### Set up and Run the Tests
+### Install Additional Tools and Services
-The test suite must pass with any submitted code. No matter whether you are writing a new patch, or evaluating someone else's, you need to be able to run the tests.
+Some Rails tests depend on additional tools that you need to install before running those specific tests.
-Install first SQLite3 and its development files for the `sqlite3` gem. On macOS
-users are done with:
+Here's the list of each gems' additional dependencies:
-```bash
-$ brew install sqlite3
-```
-
-In Ubuntu you're done with just:
-
-```bash
-$ sudo apt-get install sqlite3 libsqlite3-dev
-```
-
-If you are on Fedora or CentOS, you're done with
-
-```bash
-$ sudo yum install libsqlite3x libsqlite3x-devel
-```
-
-If you are on Arch Linux, you will need to run:
-
-```bash
-$ sudo pacman -S sqlite
-```
-
-For FreeBSD users, you're done with:
-
-```bash
-# pkg install sqlite3
-```
+* Action Cable depends on Redis
+* Active Record depends on SQLite3, MySQL and PostgreSQL
+* Active Storage depends on Yarn (additionally Yarn depends on
+ [Node.js](https://nodejs.org/)), ImageMagick, FFmpeg, muPDF, and on macOS
+ also XQuartz and Poppler.
+* Active Support depends on memcached and Redis
+* Railties depend on a JavaScript runtime environment, such as having
+ [Node.js](https://nodejs.org/) installed.
-Or compile the `databases/sqlite3` port.
+Install all the services you need to properly test the full gem you'll be
+making changes to.
-Get a recent version of [Bundler](https://bundler.io/)
+NOTE: Redis' documentation discourage installations with package managers as those are usually outdated. Installing from source and bringing the server up is straight forward and well documented on [Redis' documentation](https://redis.io/download#installation).
-```bash
-$ gem install bundler
-$ gem update bundler
-```
+NOTE: Active Record tests _must_ pass for at least MySQL, PostgreSQL, and SQLite3. Subtle differences between the various adapters have been behind the rejection of many patches that looked OK when tested only against single adapter.
-and run:
+Below you can find instructions on how to install all of the additional
+tools for different OSes.
-```bash
-$ bundle install --without db
-```
-
-This command will install all dependencies except the MySQL and PostgreSQL Ruby drivers. We will come back to these soon.
+#### macOS
-NOTE: If you would like to run the tests that use memcached, you need to ensure that you have it installed and running.
+On macOS you can use [Homebrew](https://brew.sh/) to install all of the
+additional tools.
-You can use [Homebrew](https://brew.sh/) to install memcached on macOS:
+To install all run:
```bash
-$ brew install memcached
+$ brew bundle
```
-On Ubuntu you can install it with apt-get:
+You'll also need to start each of the installed services. To list all
+available services run:
```bash
-$ sudo apt-get install memcached
+$ brew services list
```
-Or use yum on Fedora or CentOS:
+You can then start each of the services one by one like this:
```bash
-$ sudo yum install memcached
+$ brew services start mysql
```
-If you are running on Arch Linux:
-
-```bash
-$ sudo pacman -S memcached
-```
-
-For FreeBSD users, you're done with:
-
-```bash
-# pkg install memcached
-```
+Replace `mysql` with the name of the service you want to start.
-Alternatively, you can compile the `databases/memcached` port.
+#### Ubuntu
-With the dependencies now installed, you can run the test suite with:
+To install all run:
```bash
-$ bundle exec rake test
-```
-
-You can also run tests for a specific component, like Action Pack, by going into its directory and executing the same command:
+$ sudo apt-get update
+$ sudo apt-get install sqlite3 libsqlite3-dev
+ mysql-server libmysqlclient-dev
+ postgresql postgresql-client postgresql-contrib libpq-dev
+ redis-server memcached imagemagick ffmpeg mupdf mupdf-tools
-```bash
-$ cd actionpack
-$ bundle exec rake test
+# Install Yarn
+$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
+$ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
+$ sudo apt-get install yarn
```
-If you want to run the tests located in a specific directory use the `TEST_DIR` environment variable. For example, this will run the tests in the `railties/test/generators` directory only:
-
-```bash
-$ cd railties
-$ TEST_DIR=generators bundle exec rake test
-```
+#### Fedora or CentOS
-You can run the tests for a particular file by using:
+To install all run:
```bash
-$ cd actionpack
-$ bundle exec ruby -Itest test/template/form_helper_test.rb
-```
-
-Or, you can run a single test in a particular file:
+$ sudo dnf install sqlite-devel sqlite-libs
+ mysql-server mysql-devel
+ postgresql-server postgresql-devel
+ redis memcached imagemagick ffmpeg mupdf
-```bash
-$ cd actionpack
-$ bundle exec ruby -Itest path/to/test.rb -n test_name
+# Install Yarn
+# Use this command if you do not have Node.js installed
+$ curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
+# If you have Node.js installed, use this command instead
+$ curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
+$ sudo dnf install yarn
```
-### Railties Setup
-
-Some Railties tests depend on a JavaScript runtime environment, such as having [Node.js](https://nodejs.org/) installed.
-
-### Active Record Setup
-
-Active Record's test suite runs three times: once for SQLite3, once for MySQL, and once for PostgreSQL. We are going to see now how to set up the environment for them.
-
-WARNING: If you're working with Active Record code, you _must_ ensure that the tests pass for at least MySQL, PostgreSQL, and SQLite3. Subtle differences between the various adapters have been behind the rejection of many patches that looked OK when tested only against MySQL.
-
-#### Database Configuration
-
-The Active Record test suite requires a custom config file: `activerecord/test/config.yml`. An example is provided in `activerecord/test/config.example.yml` which can be copied and used as needed for your environment.
+#### Arch Linux
-#### MySQL and PostgreSQL
-
-To be able to run the suite for MySQL and PostgreSQL we need their gems. Install
-first the servers, their client libraries, and their development files.
-
-On macOS, you can run:
-
-```bash
-$ brew install mysql
-$ brew install postgresql
-```
-
-Follow the instructions given by Homebrew to start these.
-
-On Ubuntu, just run:
-
-```bash
-$ sudo apt-get install mysql-server libmysqlclient-dev
-$ sudo apt-get install postgresql postgresql-client postgresql-contrib libpq-dev
-```
-
-On Fedora or CentOS, just run:
+To install all run:
```bash
-$ sudo yum install mysql-server mysql-devel
-$ sudo yum install postgresql-server postgresql-devel
+$ sudo pacman -S sqlite
+ mariadb libmariadbclient mariadb-clients
+ postgresql postgresql-libs
+ redis memcached imagemagick ffmpeg mupdf mupdf-tools poppler
+ yarn
+$ sudo systemctl start redis
```
-If you are running Arch Linux, MySQL isn't supported anymore so you will need to
-use MariaDB instead (see [this announcement](https://www.archlinux.org/news/mariadb-replaces-mysql-in-repositories/)):
+NOTE: If you are running Arch Linux, MySQL isn't supported anymore so you will need to
+use MariaDB instead (see [this announcement](https://www.archlinux.org/news/mariadb-replaces-mysql-in-repositories/)).
-```bash
-$ sudo pacman -S mariadb libmariadbclient mariadb-clients
-$ sudo pacman -S postgresql postgresql-libs
-```
+#### FreeBSD
-FreeBSD users will have to run the following:
+To install all run:
```bash
-# pkg install mysql56-client mysql56-server
-# pkg install postgresql94-client postgresql94-server
+# pkg install sqlite3
+ mysql80-client mysql80-server
+ postgresql11-client postgresql11-server
+ memcached imagemagick ffmpeg mupdf
+ yarn
+# portmaster databases/redis
```
-Or install them through ports (they are located under the `databases` folder).
-If you run into troubles during the installation of MySQL, please see
-[the MySQL documentation](http://dev.mysql.com/doc/refman/5.1/en/freebsd-installation.html).
+Or install everyting through ports (these packages are located under the
+`databases` folder).
-After that, run:
+NOTE: If you run into troubles during the installation of MySQL, please see
+[the MySQL documentation](https://dev.mysql.com/doc/refman/8.0/en/freebsd-installation.html).
-```bash
-$ rm .bundle/config
-$ bundle install
-```
+### Database Configuration
-First, we need to delete `.bundle/config` because Bundler remembers in that file that we didn't want to install the "db" group (alternatively you can edit the file).
+There are couple of additional steps required to configure database engines
+required for running Active Record tests.
In order to be able to run the test suite against MySQL you need to create a user named `rails` with privileges on the test databases:
@@ -247,13 +181,6 @@ mysql> GRANT ALL PRIVILEGES ON inexistent_activerecord_unittest.*
to 'rails'@'localhost';
```
-and create the test databases:
-
-```bash
-$ cd activerecord
-$ bundle exec rake db:mysql:build
-```
-
PostgreSQL's authentication works differently. To setup the development environment
with your development account, on Linux or BSD, you just have to run:
@@ -267,21 +194,24 @@ and for macOS:
$ createuser --superuser $USER
```
-Then, you need to create the test databases with:
+Then, you need to create the test databases for both MySQL and PostgreSQL with:
```bash
$ cd activerecord
-$ bundle exec rake db:postgresql:build
+$ bundle exec rake db:create
```
-It is possible to build databases for both PostgreSQL and MySQL with:
+NOTE: You'll see the following warning (or localized warning) during activating HStore extension in PostgreSQL 9.1.x or earlier: "WARNING: => is deprecated as an operator".
+
+You can also create test databases for each database engine separately:
```bash
$ cd activerecord
-$ bundle exec rake db:create
+$ bundle exec rake db:mysql:build
+$ bundle exec rake db:postgresql:build
```
-You can cleanup the databases using:
+and you can drop the databases using:
```bash
$ cd activerecord
@@ -290,138 +220,40 @@ $ bundle exec rake db:drop
NOTE: Using the Rake task to create the test databases ensures they have the correct character set and collation.
-NOTE: You'll see the following warning (or localized warning) during activating HStore extension in PostgreSQL 9.1.x or earlier: "WARNING: => is deprecated as an operator".
-
If you're using another database, check the file `activerecord/test/config.yml` or `activerecord/test/config.example.yml` for default connection information. You can edit `activerecord/test/config.yml` to provide different credentials on your machine if you must, but obviously you should not push any such changes back to Rails.
-### Action Cable Setup
-
-Action Cable uses Redis as its default subscriptions adapter ([read more](action_cable_overview.html#broadcasting)). Thus, in order to have Action Cable's tests passing you need to install and have Redis running.
-
-#### Install Redis From Source
+### Install JavaScript dependencies
-Redis' documentation discourage installations with package managers as those are usually outdated. Installing from source and bringing the server up is straight forward and well documented on [Redis' documentation](https://redis.io/download#installation).
-
-#### Install Redis From Package Manager
-
-On macOS, you can run:
-
-```bash
-$ brew install redis
-```
-
-Follow the instructions given by Homebrew to start these.
-
-On Ubuntu, just run:
-
-```bash
-$ sudo apt-get install redis-server
-```
-
-On Fedora or CentOS (requires EPEL enabled), just run:
-
-```bash
-$ sudo yum install redis
-```
-
-If you are running Arch Linux, just run:
-
-```bash
-$ sudo pacman -S redis
-$ sudo systemctl start redis
-```
-
-FreeBSD users will have to run the following:
-
-```bash
-# portmaster databases/redis
-```
-
-### Active Storage Setup
-
-When working on Active Storage, it is important to note that you need to
-install its JavaScript dependencies while working on that section of the
-codebase. In order to install these dependencies, it is necessary to
-have Yarn, a Node.js package manager, available on your system. A
-prerequisite for installing this package manager is that
-[Node.js](https://nodejs.org) is installed.
-
-
-On macOS, you can run:
-
-```bash
-$ brew install yarn
-```
-
-On Ubuntu, you can run:
-
-```bash
-$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
-$ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
-
-$ sudo apt-get update && sudo apt-get install yarn
-```
-
-On Fedora or CentOS, just run:
-
-```bash
-$ sudo wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo
-
-$ sudo yum install yarn
-```
-
-Finally, after installing Yarn, you will need to run the following
-command inside of the `activestorage` directory to install the dependencies:
+If you installed Yarn, you will need to install the javascript dependencies:
```bash
+$ cd activestorage
$ yarn install
```
-Extracting previews, tested in Active Storage's test suite requires third-party
-applications, ImageMagick for images, FFmpeg for video and muPDF for PDFs, and on macOS also XQuartz
-and Poppler. Without these applications installed, Active Storage tests will
-raise errors.
+### Install Bundler gem
-On macOS you can run:
+Get a recent version of [Bundler](https://bundler.io/)
```bash
-$ brew install ffmpeg
-$ brew install imagemagick
-$ brew cask install xquartz
-$ brew install mupdf-tools
-$ brew install poppler
+$ gem install bundler
+$ gem update bundler
```
-On Ubuntu, you can run:
+and run:
```bash
-$ sudo apt-get update
-$ sudo apt-get install ffmpeg
-$ sudo apt-get install imagemagick
-$ sudo apt-get install mupdf mupdf-tools
+$ bundle install
```
-On Fedora or CentOS, just run:
+or:
```bash
-$ sudo yum install ffmpeg
-$ sudo yum install imagemagick
-$ sudo yum install mupdf
+$ bundle install --without db
```
-FreeBSD users can just run:
+if you don't need to run Active Record tests.
-```bash
-# pkg install imagemagick
-# pkg install ffmpeg
-# pkg install mupdf
-```
-
-On Arch Linux, you can run:
+### Contribute to Rails
-```bash
-$ sudo pacman -S ffmpeg
-$ sudo pacman -S imagemagick
-$ sudo pacman -S mupdf mupdf-tools
-$ sudo pacman -S poppler
-```
+After you've setup everything, read how you can start [contributing](contributing_to_ruby_on_rails.html#running-an-application-against-your-local-branch).
diff --git a/guides/source/ruby_on_rails_guides_guidelines.md b/guides/source/ruby_on_rails_guides_guidelines.md
index f5c0ba5b2d..4b56cf6296 100644
--- a/guides/source/ruby_on_rails_guides_guidelines.md
+++ b/guides/source/ruby_on_rails_guides_guidelines.md
@@ -107,8 +107,8 @@ HTML Guides
-----------
Before generating the guides, make sure that you have the latest version of
-Bundler installed on your system. As of this writing, you must install Bundler
-1.3.5 or later on your device.
+Bundler installed on your system. You can find the latest Bundler version
+[here](https://rubygems.org/gems/bundler). As of this writing, it's v1.17.1.
To install the latest version of Bundler, run `gem install bundler`.
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index f56f79b8d4..33002790d4 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -258,8 +258,8 @@ module Rails
class_option :skip_bundle, type: :boolean, aliases: "-B", default: false,
desc: "Don't run bundle install"
- class_option :webpack, type: :string, default: nil,
- desc: "Preconfigure Webpack with a particular framework (options: #{WEBPACKS.join('/')})"
+ class_option :webpack, type: :string, aliases: "--webpacker", default: nil,
+ desc: "Preconfigure Webpack with a particular framework (options: #{WEBPACKS.join(", ")})"
class_option :skip_webpack_install, type: :boolean, default: false,
desc: "Don't run Webpack install"
diff --git a/railties/test/application/bin_setup_test.rb b/railties/test/application/bin_setup_test.rb
index d02100d94c..a952d2466b 100644
--- a/railties/test/application/bin_setup_test.rb
+++ b/railties/test/application/bin_setup_test.rb
@@ -45,6 +45,8 @@ module ApplicationTests
output.sub!(/^Resolving dependencies\.\.\.\n/, "")
# Suppress Bundler platform warnings from output
output.gsub!(/^The dependency .* will be unused .*\.\n/, "")
+ # Ignore warnings such as `Psych.safe_load is deprecated`
+ output.gsub!(/^warning:\s.*\n/, "")
assert_equal(<<~OUTPUT, output)
== Installing dependencies ==
diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb
index e98a41fb26..0d7645e794 100644
--- a/railties/test/application/test_runner_test.rb
+++ b/railties/test/application/test_runner_test.rb
@@ -562,6 +562,30 @@ module ApplicationTests
assert_no_match "create_table(:users)", output
end
+ def test_run_in_parallel_with_unmarshable_exception
+ file = app_file "test/fail_test.rb", <<-RUBY
+ require "test_helper"
+ class FailTest < ActiveSupport::TestCase
+ class BadError < StandardError
+ def initialize
+ super
+ @proc = ->{ }
+ end
+ end
+
+ test "fail" do
+ raise BadError
+ assert true
+ end
+ end
+ RUBY
+
+ output = run_test_command(file)
+
+ assert_match "DRb::DRbRemoteError: FailTest::BadError", output
+ assert_match "1 runs, 0 assertions, 0 failures, 1 errors", output
+ end
+
def test_raise_error_when_specified_file_does_not_exist
error = capture(:stderr) { run_test_command("test/not_exists.rb", stderr: true) }
assert_match(%r{cannot load such file.+test/not_exists\.rb}, error)