aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile.lock1
-rw-r--r--actioncable/.gitignore2
-rw-r--r--actioncable/Rakefile44
-rw-r--r--actioncable/actioncable.gemspec7
-rw-r--r--actioncable/app/assets/javascripts/action_cable.coffee.erb (renamed from actioncable/lib/assets/javascripts/action_cable.coffee.erb)2
-rw-r--r--actioncable/app/assets/javascripts/action_cable/connection.coffee (renamed from actioncable/lib/assets/javascripts/action_cable/connection.coffee)0
-rw-r--r--actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee (renamed from actioncable/lib/assets/javascripts/action_cable/connection_monitor.coffee)0
-rw-r--r--actioncable/app/assets/javascripts/action_cable/consumer.coffee (renamed from actioncable/lib/assets/javascripts/action_cable/consumer.coffee)8
-rw-r--r--actioncable/app/assets/javascripts/action_cable/subscription.coffee (renamed from actioncable/lib/assets/javascripts/action_cable/subscription.coffee)0
-rw-r--r--actioncable/app/assets/javascripts/action_cable/subscriptions.coffee (renamed from actioncable/lib/assets/javascripts/action_cable/subscriptions.coffee)0
-rw-r--r--actioncable/test/client_test.rb10
-rw-r--r--actionmailer/Rakefile3
-rw-r--r--actionpack/Rakefile3
-rw-r--r--actionpack/lib/action_controller/metal.rb1
-rw-r--r--actionpack/lib/action_dispatch/testing/test_process.rb1
-rw-r--r--actionpack/test/controller/new_base/bare_metal_test.rb16
-rw-r--r--actionpack/test/controller/render_test.rb2
-rw-r--r--actionview/Rakefile3
-rw-r--r--activejob/Rakefile3
-rw-r--r--activemodel/Rakefile3
-rw-r--r--activerecord/Rakefile3
-rw-r--r--activerecord/lib/active_record/associations.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb29
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb86
-rw-r--r--activerecord/lib/active_record/connection_adapters/column.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb70
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb39
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb42
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb19
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb17
-rw-r--r--activerecord/lib/active_record/internal_metadata.rb16
-rw-r--r--activerecord/lib/active_record/persistence.rb6
-rw-r--r--activerecord/lib/active_record/railtie.rb2
-rw-r--r--activerecord/lib/active_record/reflection.rb68
-rw-r--r--activerecord/lib/active_record/schema_migration.rb17
-rw-r--r--activerecord/lib/rails/generators/active_record/migration/templates/migration.rb4
-rw-r--r--activerecord/test/cases/adapters/mysql2/enum_test.rb5
-rw-r--r--activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb5
-rw-r--r--activerecord/test/cases/adapters/postgresql/extension_migration_test.rb12
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb6
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb6
-rw-r--r--activerecord/test/cases/ar_schema_test.rb2
-rw-r--r--activerecord/test/cases/migration/compatibility_test.rb30
-rw-r--r--activerecord/test/cases/migration/table_and_index_test.rb24
-rw-r--r--activerecord/test/cases/primary_keys_test.rb27
-rw-r--r--activerecord/test/schema/mysql2_specific_schema.rb11
-rw-r--r--activerecord/test/schema/schema.rb11
-rw-r--r--activesupport/Rakefile4
-rw-r--r--guides/bug_report_templates/generic_master.rb3
-rw-r--r--guides/source/api_app.md3
-rw-r--r--guides/source/asset_pipeline.md17
-rw-r--r--guides/source/command_line.md2
-rw-r--r--guides/source/configuring.md4
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md2
-rw-r--r--guides/source/rails_on_rack.md10
-rw-r--r--guides/source/testing.md47
-rw-r--r--railties/Rakefile3
-rw-r--r--railties/lib/rails/engine/commands.rb35
-rw-r--r--railties/lib/rails/engine/commands_tasks.rb116
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb1
-rw-r--r--railties/lib/rails/tasks/engine.rake4
-rw-r--r--railties/test/generators/plugin_generator_test.rb2
-rw-r--r--railties/test/generators/scaffold_generator_test.rb8
-rw-r--r--tasks/release.rb2
66 files changed, 555 insertions, 387 deletions
diff --git a/Gemfile.lock b/Gemfile.lock
index b15d3498a8..ba41d0705f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -31,7 +31,6 @@ PATH
specs:
actioncable (5.0.0.beta1.1)
actionpack (= 5.0.0.beta1.1)
- coffee-rails (~> 4.1.0)
nio4r (~> 1.2)
websocket-driver (~> 0.6.1)
actionmailer (5.0.0.beta1.1)
diff --git a/actioncable/.gitignore b/actioncable/.gitignore
new file mode 100644
index 0000000000..0a04b29786
--- /dev/null
+++ b/actioncable/.gitignore
@@ -0,0 +1,2 @@
+/lib/assets/compiled
+/tmp
diff --git a/actioncable/Rakefile b/actioncable/Rakefile
index b6c56e9195..1d77fc7067 100644
--- a/actioncable/Rakefile
+++ b/actioncable/Rakefile
@@ -1,9 +1,16 @@
require 'rake/testtask'
+require 'pathname'
+require 'sprockets'
+require 'coffee-script'
+require 'action_cable'
dir = File.dirname(__FILE__)
task :default => :test
+task :package => "assets:compile"
+task "package:clean" => "assets:clean"
+
Rake::TestTask.new do |t|
t.libs << "test"
t.test_files = Dir.glob("#{dir}/test/**/*_test.rb")
@@ -11,3 +18,40 @@ Rake::TestTask.new do |t|
t.verbose = true
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
end
+
+namespace :assets do
+ root_path = Pathname.new(dir)
+ destination_path = root_path.join("lib/assets/compiled")
+
+ desc "Compile dist/action_cable.js"
+ task :compile do
+ puts 'Compiling Action Cable assets...'
+
+ precompile_list = %w(action_cable.js)
+
+ environment = Sprockets::Environment.new
+ environment.gzip = false
+ Pathname.glob(root_path.join("app/assets/*/")) do |subdir|
+ environment.append_path subdir
+ end
+
+ compile_path = root_path.join("tmp/sprockets")
+ compile_path.rmtree if compile_path.exist?
+ compile_path.mkpath
+
+ manifest = Sprockets::Manifest.new(environment.index, compile_path)
+ manifest.compile(precompile_list)
+
+ destination_path.rmtree if destination_path.exist?
+ manifest.assets.each do |path, fingerprint_path|
+ destination_path.join(path).dirname.mkpath
+ FileUtils.cp(compile_path.join(fingerprint_path), destination_path.join(path))
+ end
+
+ puts 'Done'
+ end
+
+ task :clean do
+ destination_path.rmtree if destination_path.exist?
+ end
+end
diff --git a/actioncable/actioncable.gemspec b/actioncable/actioncable.gemspec
index 14f968f1ef..c65ff7871f 100644
--- a/actioncable/actioncable.gemspec
+++ b/actioncable/actioncable.gemspec
@@ -20,13 +20,6 @@ Gem::Specification.new do |s|
s.add_dependency 'actionpack', version
- s.add_dependency 'coffee-rails', '~> 4.1.0'
s.add_dependency 'nio4r', '~> 1.2'
s.add_dependency 'websocket-driver', '~> 0.6.1'
-
- s.add_development_dependency 'em-hiredis', '~> 0.3.0'
- s.add_development_dependency 'mocha'
- s.add_development_dependency 'pg'
- s.add_development_dependency 'puma'
- s.add_development_dependency 'redis', '~> 3.0'
end
diff --git a/actioncable/lib/assets/javascripts/action_cable.coffee.erb b/actioncable/app/assets/javascripts/action_cable.coffee.erb
index 7daea4ebcd..18a48c0610 100644
--- a/actioncable/lib/assets/javascripts/action_cable.coffee.erb
+++ b/actioncable/app/assets/javascripts/action_cable.coffee.erb
@@ -1,5 +1,5 @@
#= require_self
-#= require action_cable/consumer
+#= require ./action_cable/consumer
@ActionCable =
INTERNAL: <%= ActionCable::INTERNAL.to_json %>
diff --git a/actioncable/lib/assets/javascripts/action_cable/connection.coffee b/actioncable/app/assets/javascripts/action_cable/connection.coffee
index fbd7dbd35b..fbd7dbd35b 100644
--- a/actioncable/lib/assets/javascripts/action_cable/connection.coffee
+++ b/actioncable/app/assets/javascripts/action_cable/connection.coffee
diff --git a/actioncable/lib/assets/javascripts/action_cable/connection_monitor.coffee b/actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee
index 99b9a1c6d5..99b9a1c6d5 100644
--- a/actioncable/lib/assets/javascripts/action_cable/connection_monitor.coffee
+++ b/actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee
diff --git a/actioncable/lib/assets/javascripts/action_cable/consumer.coffee b/actioncable/app/assets/javascripts/action_cable/consumer.coffee
index fcd8d0fb6c..717c0641a9 100644
--- a/actioncable/lib/assets/javascripts/action_cable/consumer.coffee
+++ b/actioncable/app/assets/javascripts/action_cable/consumer.coffee
@@ -1,7 +1,7 @@
-#= require action_cable/connection
-#= require action_cable/connection_monitor
-#= require action_cable/subscriptions
-#= require action_cable/subscription
+#= require ./connection
+#= require ./connection_monitor
+#= require ./subscriptions
+#= require ./subscription
# The ActionCable.Consumer establishes the connection to a server-side Ruby Connection object. Once established,
# the ActionCable.ConnectionMonitor will ensure that its properly maintained through heartbeats and checking for stale updates.
diff --git a/actioncable/lib/assets/javascripts/action_cable/subscription.coffee b/actioncable/app/assets/javascripts/action_cable/subscription.coffee
index 339d676933..339d676933 100644
--- a/actioncable/lib/assets/javascripts/action_cable/subscription.coffee
+++ b/actioncable/app/assets/javascripts/action_cable/subscription.coffee
diff --git a/actioncable/lib/assets/javascripts/action_cable/subscriptions.coffee b/actioncable/app/assets/javascripts/action_cable/subscriptions.coffee
index ae041ffa2b..ae041ffa2b 100644
--- a/actioncable/lib/assets/javascripts/action_cable/subscriptions.coffee
+++ b/actioncable/app/assets/javascripts/action_cable/subscriptions.coffee
diff --git a/actioncable/test/client_test.rb b/actioncable/test/client_test.rb
index d7eecfa322..199d2b90a3 100644
--- a/actioncable/test/client_test.rb
+++ b/actioncable/test/client_test.rb
@@ -32,6 +32,7 @@ class ClientTest < ActionCable::TestCase
server.config.channel_load_paths = [File.expand_path('client', __dir__)]
Thread.new { EventMachine.run } unless EventMachine.reactor_running?
+ Thread.pass until EventMachine.reactor_running?
# faye-websocket is warning-rich
@previous_verbose, $VERBOSE = $VERBOSE, nil
@@ -145,15 +146,6 @@ class ClientTest < ActionCable::TestCase
@ws.close
@closed.wait(WAIT_WHEN_EXPECTING_EVENT)
end
-
- def close!
- sock = BasicSocket.for_fd(@ws.instance_variable_get(:@stream).detach)
-
- # Force a TCP reset
- sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, [1, 0].pack('ii'))
-
- sock.close
- end
end
def faye_client(port)
diff --git a/actionmailer/Rakefile b/actionmailer/Rakefile
index 7197ea5e27..54e6cff48d 100644
--- a/actionmailer/Rakefile
+++ b/actionmailer/Rakefile
@@ -3,6 +3,9 @@ require 'rake/testtask'
desc "Default Task"
task default: [ :test ]
+task :package
+task "package:clean"
+
# Run the unit tests
Rake::TestTask.new { |t|
t.libs << "test"
diff --git a/actionpack/Rakefile b/actionpack/Rakefile
index 601263bfac..37a269cffd 100644
--- a/actionpack/Rakefile
+++ b/actionpack/Rakefile
@@ -5,6 +5,9 @@ test_files = Dir.glob('test/**/*_test.rb')
desc "Default Task"
task :default => :test
+task :package
+task "package:clean"
+
# Run the unit tests
Rake::TestTask.new do |t|
t.libs << 'test'
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index f6a93a8940..1641d01c30 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -174,6 +174,7 @@ module ActionController
def response_body=(body)
body = [body] unless body.nil? || body.respond_to?(:each)
response.reset_body!
+ return unless body
body.each { |part|
next if part.empty?
response.write part
diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb
index eca0439909..1ecd7d14a7 100644
--- a/actionpack/lib/action_dispatch/testing/test_process.rb
+++ b/actionpack/lib/action_dispatch/testing/test_process.rb
@@ -1,6 +1,5 @@
require 'action_dispatch/middleware/cookies'
require 'action_dispatch/middleware/flash'
-require 'active_support/core_ext/hash/indifferent_access'
module ActionDispatch
module TestProcess
diff --git a/actionpack/test/controller/new_base/bare_metal_test.rb b/actionpack/test/controller/new_base/bare_metal_test.rb
index c226fa57ee..ee3c498b1c 100644
--- a/actionpack/test/controller/new_base/bare_metal_test.rb
+++ b/actionpack/test/controller/new_base/bare_metal_test.rb
@@ -40,6 +40,22 @@ module BareMetalTest
end
end
+ class BareEmptyController < ActionController::Metal
+ def index
+ self.response_body = nil
+ end
+ end
+
+ class BareEmptyTest < ActiveSupport::TestCase
+ test "response body is nil" do
+ controller = BareEmptyController.new
+ controller.set_request!(ActionDispatch::Request.empty)
+ controller.set_response!(BareController.make_response!(controller.request))
+ controller.index
+ assert_equal nil, controller.response_body
+ end
+ end
+
class HeadController < ActionController::Metal
include ActionController::Head
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 9430ab8db8..c814d4ea54 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -275,7 +275,7 @@ class ExpiresInRenderTest < ActionController::TestCase
file.write "secrets!"
file.flush
assert_raises ActionView::MissingTemplate do
- response = get :dynamic_render, params: { id: file.path }
+ get :dynamic_render, params: { id: file.path }
end
ensure
file.close
diff --git a/actionview/Rakefile b/actionview/Rakefile
index 93be50721d..d41030c650 100644
--- a/actionview/Rakefile
+++ b/actionview/Rakefile
@@ -3,6 +3,9 @@ require 'rake/testtask'
desc "Default Task"
task :default => :test
+task :package
+task "package:clean"
+
# Run the unit tests
desc "Run all unit tests"
diff --git a/activejob/Rakefile b/activejob/Rakefile
index d9648a7f16..2a853b4b6b 100644
--- a/activejob/Rakefile
+++ b/activejob/Rakefile
@@ -6,6 +6,9 @@ ACTIVEJOB_ADAPTERS -= %w(queue_classic) if defined?(JRUBY_VERSION)
task default: :test
task test: 'test:default'
+task :package
+task "package:clean"
+
namespace :test do
desc 'Run all adapter tests'
task :default do
diff --git a/activemodel/Rakefile b/activemodel/Rakefile
index 5a67f0a151..9982d49bcb 100644
--- a/activemodel/Rakefile
+++ b/activemodel/Rakefile
@@ -4,6 +4,9 @@ dir = File.dirname(__FILE__)
task :default => :test
+task :package
+task "package:clean"
+
Rake::TestTask.new do |t|
t.libs << "test"
t.test_files = Dir.glob("#{dir}/test/cases/**/*_test.rb")
diff --git a/activerecord/Rakefile b/activerecord/Rakefile
index 0564dca94a..46df733cfe 100644
--- a/activerecord/Rakefile
+++ b/activerecord/Rakefile
@@ -20,6 +20,9 @@ end
desc 'Run mysql2, sqlite, and postgresql tests by default'
task :default => :test
+task :package
+task "package:clean"
+
desc 'Run mysql2, sqlite, and postgresql tests'
task :test do
tasks = defined?(JRUBY_VERSION) ?
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index f6d8e8a342..e13fe33b85 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1593,6 +1593,8 @@ module ActiveRecord
# If true, the associated object will be touched (the updated_at/on attributes set to current time)
# when this record is either saved or destroyed. If you specify a symbol, that attribute
# will be updated with the current time in addition to the updated_at/on attribute.
+ # Please note that with touching no validation is performed and only the +after_touch+,
+ # +after_commit+ and +after_rollback+ callbacks are executed.
# [:inverse_of]
# Specifies the name of the #has_one or #has_many association on the associated
# object that is the inverse of this #belongs_to association. Does not work in
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 c7aff63228..cc245587c1 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -92,7 +92,9 @@ module ActiveRecord
# Returns an array of Column objects for the table specified by +table_name+.
# See the concrete implementation for details on the expected parameter values.
- def columns(table_name) end
+ def columns(table_name)
+ raise NotImplementedError, "#columns is not implemented"
+ end
# Checks to see if a column exists in a given table.
#
@@ -110,18 +112,25 @@ module ActiveRecord
#
def column_exists?(table_name, column_name, type = nil, options = {})
column_name = column_name.to_s
- columns(table_name).any?{ |c| c.name == column_name &&
- (!type || c.type == type) &&
- (!options.key?(:limit) || c.limit == options[:limit]) &&
- (!options.key?(:precision) || c.precision == options[:precision]) &&
- (!options.key?(:scale) || c.scale == options[:scale]) &&
- (!options.key?(:default) || c.default == options[:default]) &&
- (!options.key?(:null) || c.null == options[:null]) }
+ checks = []
+ checks << lambda { |c| c.name == column_name }
+ checks << lambda { |c| c.type == type } if type
+ (migration_keys - [:name]).each do |attr|
+ checks << lambda { |c| c.send(attr) == options[attr] } if options.key?(attr)
+ end
+
+ columns(table_name).any? { |c| checks.all? { |check| check[c] } }
end
# Returns just a table's primary key
def primary_key(table_name)
pks = primary_keys(table_name)
+ warn <<-WARNING.strip_heredoc if pks.count > 1
+ WARNING: Rails does not support composite primary key.
+
+ #{table_name} has composite primary key. Composite primary key is ignored.
+ WARNING
+
pks.first if pks.one?
end
@@ -972,6 +981,10 @@ module ActiveRecord
ActiveRecord::InternalMetadata.create_table
end
+ def internal_string_options_for_primary_key # :nodoc:
+ { primary_key: true }
+ end
+
def assume_migrated_upto_version(version, migrations_paths)
migrations_paths = Array(migrations_paths)
version = version.to_i
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 5a9020ead5..70d7956baa 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -1,5 +1,6 @@
require 'active_record/connection_adapters/abstract_adapter'
require 'active_record/connection_adapters/mysql/column'
+require 'active_record/connection_adapters/mysql/explain_pretty_printer'
require 'active_record/connection_adapters/mysql/schema_creation'
require 'active_record/connection_adapters/mysql/schema_definitions'
require 'active_record/connection_adapters/mysql/schema_dumper'
@@ -31,12 +32,6 @@ module ActiveRecord
class_attribute :emulate_booleans
self.emulate_booleans = true
- LOST_CONNECTION_ERROR_MESSAGES = [
- "Server shutdown in progress",
- "Broken pipe",
- "Lost connection to MySQL server during query",
- "MySQL server has gone away" ]
-
QUOTED_TRUE, QUOTED_FALSE = '1', '0'
NATIVE_DATABASE_TYPES = {
@@ -72,14 +67,12 @@ module ActiveRecord
end
end
- MAX_INDEX_LENGTH_FOR_CHARSETS_OF_4BYTES_MAXLEN = 191
CHARSETS_OF_4BYTES_MAXLEN = ['utf8mb4', 'utf16', 'utf16le', 'utf32']
- def initialize_schema_migrations_table
- if CHARSETS_OF_4BYTES_MAXLEN.include?(charset)
- ActiveRecord::SchemaMigration.create_table(MAX_INDEX_LENGTH_FOR_CHARSETS_OF_4BYTES_MAXLEN)
- else
- ActiveRecord::SchemaMigration.create_table
- end
+
+ def internal_string_options_for_primary_key # :nodoc:
+ super.tap { |options|
+ options[:collation] = collation.sub(/\A[^_]+/, 'utf8') if CHARSETS_OF_4BYTES_MAXLEN.include?(charset)
+ }
end
def version
@@ -238,72 +231,7 @@ module ActiveRecord
result = exec_query(sql, 'EXPLAIN', binds)
elapsed = Time.now - start
- ExplainPrettyPrinter.new.pp(result, elapsed)
- end
-
- class ExplainPrettyPrinter # :nodoc:
- # Pretty prints the result of an EXPLAIN in a way that resembles the output of the
- # MySQL shell:
- #
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
- # | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
- # | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
- # | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
- # 2 rows in set (0.00 sec)
- #
- # This is an exercise in Ruby hyperrealism :).
- def pp(result, elapsed)
- widths = compute_column_widths(result)
- separator = build_separator(widths)
-
- pp = []
-
- pp << separator
- pp << build_cells(result.columns, widths)
- pp << separator
-
- result.rows.each do |row|
- pp << build_cells(row, widths)
- end
-
- pp << separator
- pp << build_footer(result.rows.length, elapsed)
-
- pp.join("\n") + "\n"
- end
-
- private
-
- def compute_column_widths(result)
- [].tap do |widths|
- result.columns.each_with_index do |column, i|
- cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s}
- widths << cells_in_column.map(&:length).max
- end
- end
- end
-
- def build_separator(widths)
- padding = 1
- '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
- end
-
- def build_cells(items, widths)
- cells = []
- items.each_with_index do |item, i|
- item = 'NULL' if item.nil?
- justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
- cells << item.to_s.send(justifier, widths[i])
- end
- '| ' + cells.join(' | ') + ' |'
- end
-
- def build_footer(nrows, elapsed)
- rows_label = nrows == 1 ? 'row' : 'rows'
- "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
- end
+ MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
end
def clear_cache!
diff --git a/activerecord/lib/active_record/connection_adapters/column.rb b/activerecord/lib/active_record/connection_adapters/column.rb
index 81de7c03fb..10f908538f 100644
--- a/activerecord/lib/active_record/connection_adapters/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/column.rb
@@ -30,7 +30,7 @@ module ActiveRecord
end
def bigint?
- /bigint/ === sql_type
+ /\Abigint\b/ === sql_type
end
# Returns the human name of the column name.
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb b/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb
new file mode 100644
index 0000000000..1820853196
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb
@@ -0,0 +1,70 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module MySQL
+ class ExplainPrettyPrinter # :nodoc:
+ # Pretty prints the result of an EXPLAIN in a way that resembles the output of the
+ # MySQL shell:
+ #
+ # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
+ # | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+ # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
+ # | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+ # | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
+ # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
+ # 2 rows in set (0.00 sec)
+ #
+ # This is an exercise in Ruby hyperrealism :).
+ def pp(result, elapsed)
+ widths = compute_column_widths(result)
+ separator = build_separator(widths)
+
+ pp = []
+
+ pp << separator
+ pp << build_cells(result.columns, widths)
+ pp << separator
+
+ result.rows.each do |row|
+ pp << build_cells(row, widths)
+ end
+
+ pp << separator
+ pp << build_footer(result.rows.length, elapsed)
+
+ pp.join("\n") + "\n"
+ end
+
+ private
+
+ def compute_column_widths(result)
+ [].tap do |widths|
+ result.columns.each_with_index do |column, i|
+ cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s}
+ widths << cells_in_column.map(&:length).max
+ end
+ end
+ end
+
+ def build_separator(widths)
+ padding = 1
+ '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
+ end
+
+ def build_cells(items, widths)
+ cells = []
+ items.each_with_index do |item, i|
+ item = 'NULL' if item.nil?
+ justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
+ cells << item.to_s.send(justifier, widths[i])
+ end
+ '| ' + cells.join(' | ') + ' |'
+ end
+
+ def build_footer(nrows, elapsed)
+ rows_label = nrows == 1 ? 'row' : 'rows'
+ "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
index 8c7cfae7c1..6aa264d766 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
@@ -4,44 +4,7 @@ module ActiveRecord
module DatabaseStatements
def explain(arel, binds = [])
sql = "EXPLAIN #{to_sql(arel, binds)}"
- ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
- end
-
- class ExplainPrettyPrinter # :nodoc:
- # Pretty prints the result of an EXPLAIN in a way that resembles the output of the
- # PostgreSQL shell:
- #
- # QUERY PLAN
- # ------------------------------------------------------------------------------
- # Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
- # Join Filter: (posts.user_id = users.id)
- # -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4)
- # Index Cond: (id = 1)
- # -> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4)
- # Filter: (posts.user_id = 1)
- # (6 rows)
- #
- def pp(result)
- header = result.columns.first
- lines = result.rows.map(&:first)
-
- # We add 2 because there's one char of padding at both sides, note
- # the extra hyphens in the example above.
- width = [header, *lines].map(&:length).max + 2
-
- pp = []
-
- pp << header.center(width).rstrip
- pp << '-' * width
-
- pp += lines.map {|line| " #{line}"}
-
- nrows = result.rows.length
- rows_label = nrows == 1 ? 'row' : 'rows'
- pp << "(#{nrows} #{rows_label})"
-
- pp.join("\n") + "\n"
- end
+ PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
end
def select_value(arel, name = nil, binds = [])
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb b/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb
new file mode 100644
index 0000000000..789b88912c
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb
@@ -0,0 +1,42 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module PostgreSQL
+ class ExplainPrettyPrinter # :nodoc:
+ # Pretty prints the result of an EXPLAIN in a way that resembles the output of the
+ # PostgreSQL shell:
+ #
+ # QUERY PLAN
+ # ------------------------------------------------------------------------------
+ # Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
+ # Join Filter: (posts.user_id = users.id)
+ # -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4)
+ # Index Cond: (id = 1)
+ # -> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4)
+ # Filter: (posts.user_id = 1)
+ # (6 rows)
+ #
+ def pp(result)
+ header = result.columns.first
+ lines = result.rows.map(&:first)
+
+ # We add 2 because there's one char of padding at both sides, note
+ # the extra hyphens in the example above.
+ width = [header, *lines].map(&:length).max + 2
+
+ pp = []
+
+ pp << header.center(width).rstrip
+ pp << '-' * width
+
+ pp += lines.map {|line| " #{line}"}
+
+ nrows = result.rows.length
+ rows_label = nrows == 1 ? 'row' : 'rows'
+ pp << "(#{nrows} #{rows_label})"
+
+ pp.join("\n") + "\n"
+ end
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb
index 2163674019..dcc12ae2a4 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb
@@ -3,8 +3,6 @@ module ActiveRecord
module PostgreSQL
module OID # :nodoc:
class Money < Type::Decimal # :nodoc:
- class_attribute :precision
-
def type
:money
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 2de6fbfaf0..d69c2e186b 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -5,6 +5,7 @@ require 'pg'
require "active_record/connection_adapters/abstract_adapter"
require "active_record/connection_adapters/postgresql/column"
require "active_record/connection_adapters/postgresql/database_statements"
+require "active_record/connection_adapters/postgresql/explain_pretty_printer"
require "active_record/connection_adapters/postgresql/oid"
require "active_record/connection_adapters/postgresql/quoting"
require "active_record/connection_adapters/postgresql/referential_integrity"
@@ -645,12 +646,6 @@ module ActiveRecord
# connected server's characteristics.
def connect
@connection = PGconn.connect(@connection_parameters)
-
- # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of
- # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision
- # should know about this but can't detect it there, so deal with it here.
- OID::Money.precision = (postgresql_version >= 80300) ? 19 : 10
-
configure_connection
rescue ::PG::Error => error
if error.message.include?("does not exist")
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb b/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb
new file mode 100644
index 0000000000..a946f5ebd0
--- /dev/null
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb
@@ -0,0 +1,19 @@
+module ActiveRecord
+ module ConnectionAdapters
+ module SQLite3
+ class ExplainPrettyPrinter # :nodoc:
+ # Pretty prints the result of an EXPLAIN QUERY PLAN in a way that resembles
+ # the output of the SQLite shell:
+ #
+ # 0|0|0|SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
+ # 0|1|1|SCAN TABLE posts (~100000 rows)
+ #
+ def pp(result)
+ result.rows.map do |row|
+ row.join('|')
+ end.join("\n") + "\n"
+ 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 d1893f35f5..a5cbbf0c69 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -1,5 +1,6 @@
require 'active_record/connection_adapters/abstract_adapter'
require 'active_record/connection_adapters/statement_pool'
+require 'active_record/connection_adapters/sqlite3/explain_pretty_printer'
require 'active_record/connection_adapters/sqlite3/schema_creation'
gem 'sqlite3', '~> 1.3.6'
@@ -218,21 +219,7 @@ module ActiveRecord
def explain(arel, binds = [])
sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
- ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', []))
- end
-
- class ExplainPrettyPrinter
- # Pretty prints the result of an EXPLAIN QUERY PLAN in a way that resembles
- # the output of the SQLite shell:
- #
- # 0|0|0|SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
- # 0|1|1|SCAN TABLE posts (~100000 rows)
- #
- def pp(result) # :nodoc:
- result.rows.map do |row|
- row.join('|')
- end.join("\n") + "\n"
- end
+ SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', []))
end
def exec_query(sql, name = nil, binds = [], prepare: false)
diff --git a/activerecord/lib/active_record/internal_metadata.rb b/activerecord/lib/active_record/internal_metadata.rb
index 10fee4dca2..cb4b1fc47c 100644
--- a/activerecord/lib/active_record/internal_metadata.rb
+++ b/activerecord/lib/active_record/internal_metadata.rb
@@ -5,10 +5,6 @@ module ActiveRecord
# This class is used to create a table that keeps track of values and keys such
# as which environment migrations were run in.
class InternalMetadata < ActiveRecord::Base # :nodoc:
- # Keys in mysql are limited to 191 characters, due to this no adapter can
- # use a longer key
- KEY_LIMIT = 191
-
class << self
def primary_key
"key"
@@ -18,10 +14,6 @@ module ActiveRecord
"#{table_name_prefix}#{ActiveRecord::Base.internal_metadata_table_name}#{table_name_suffix}"
end
- def index_name
- "#{table_name_prefix}unique_#{ActiveRecord::Base.internal_metadata_table_name}#{table_name_suffix}"
- end
-
def []=(key, value)
first_or_initialize(key: key).update_attributes!(value: value)
end
@@ -37,11 +29,11 @@ module ActiveRecord
# Creates an internal metadata table with columns +key+ and +value+
def create_table
unless table_exists?
- connection.create_table(table_name, id: false) do |t|
- t.column :key, :string, null: false, limit: KEY_LIMIT
- t.column :value, :string
- t.index :key, unique: true, name: index_name
+ key_options = connection.internal_string_options_for_primary_key
+ connection.create_table(table_name, id: false) do |t|
+ t.string :key, key_options
+ t.string :value
t.timestamps
end
end
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 4d661735cc..d9a394fb71 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -106,7 +106,7 @@ module ActiveRecord
# the existing record gets updated.
#
# By default, save always runs validations. If any of them fail the action
- # is cancelled and #save returns +false+. However, if you supply
+ # is cancelled and #save returns +false+, and the record won't be saved. However, if you supply
# validate: false, validations are bypassed altogether. See
# ActiveRecord::Validations for more information.
#
@@ -133,7 +133,7 @@ module ActiveRecord
# the existing record gets updated.
#
# By default, #save! always runs validations. If any of them fail
- # ActiveRecord::RecordInvalid gets raised. However, if you supply
+ # ActiveRecord::RecordInvalid gets raised, and the record won't be saved. However, if you supply
# validate: false, validations are bypassed altogether. See
# ActiveRecord::Validations for more information.
#
@@ -270,7 +270,7 @@ module ActiveRecord
alias update_attributes update
# Updates its receiver just like #update but calls #save! instead
- # of +save+, so an exception is raised if the record is invalid.
+ # of +save+, so an exception is raised if the record is invalid and saving will fail.
def update!(attributes)
# The following transaction covers any possible database side-effects of the
# attributes assignment. For example, setting the IDs of a child collection.
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index 38916f7376..f4200e96b7 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -40,7 +40,7 @@ module ActiveRecord
task :load_config do
ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
- if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH)
+ if defined?(ENGINE_ROOT) && engine = Rails::Engine.find(ENGINE_ROOT)
if engine.paths['db/migrate'].existent
ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths['db/migrate'].to_a
end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 320ced5afa..823ca1f54f 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -483,28 +483,7 @@ module ActiveRecord
# Returns +true+ if +self+ is a +has_one+ reflection.
def has_one?; false; end
- def association_class
- case macro
- when :belongs_to
- if polymorphic?
- Associations::BelongsToPolymorphicAssociation
- else
- Associations::BelongsToAssociation
- end
- when :has_many
- if options[:through]
- Associations::HasManyThroughAssociation
- else
- Associations::HasManyAssociation
- end
- when :has_one
- if options[:through]
- Associations::HasOneThroughAssociation
- else
- Associations::HasOneAssociation
- end
- end
- end
+ def association_class; raise NotImplementedError; end
def polymorphic?
options[:polymorphic]
@@ -522,14 +501,7 @@ module ActiveRecord
private
def calculate_constructable(macro, options)
- case macro
- when :belongs_to
- !polymorphic?
- when :has_one
- !options[:through]
- else
- true
- end
+ true
end
# Attempts to find the inverse association name automatically.
@@ -629,6 +601,14 @@ module ActiveRecord
def macro; :has_many; end
def collection?; true; end
+
+ def association_class
+ if options[:through]
+ Associations::HasManyThroughAssociation
+ else
+ Associations::HasManyAssociation
+ end
+ end
end
class HasOneReflection < AssociationReflection # :nodoc:
@@ -639,6 +619,20 @@ module ActiveRecord
def macro; :has_one; end
def has_one?; true; end
+
+ def association_class
+ if options[:through]
+ Associations::HasOneThroughAssociation
+ else
+ Associations::HasOneAssociation
+ end
+ end
+
+ private
+
+ def calculate_constructable(macro, options)
+ !options[:through]
+ end
end
class BelongsToReflection < AssociationReflection # :nodoc:
@@ -650,6 +644,14 @@ module ActiveRecord
def belongs_to?; true; end
+ def association_class
+ if polymorphic?
+ Associations::BelongsToPolymorphicAssociation
+ else
+ Associations::BelongsToAssociation
+ end
+ end
+
def join_keys(association_klass)
key = polymorphic? ? association_primary_key(association_klass) : association_primary_key
JoinKeys.new(key, foreign_key)
@@ -658,6 +660,12 @@ module ActiveRecord
def join_id_for(owner) # :nodoc:
owner[foreign_key]
end
+
+ private
+
+ def calculate_constructable(macro, options)
+ !polymorphic?
+ end
end
class HasAndBelongsToManyReflection < AssociationReflection # :nodoc:
diff --git a/activerecord/lib/active_record/schema_migration.rb b/activerecord/lib/active_record/schema_migration.rb
index ee4c71f304..b6cb233e03 100644
--- a/activerecord/lib/active_record/schema_migration.rb
+++ b/activerecord/lib/active_record/schema_migration.rb
@@ -16,31 +16,22 @@ module ActiveRecord
"#{table_name_prefix}#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
end
- def index_name
- "#{table_name_prefix}unique_#{ActiveRecord::Base.schema_migrations_table_name}#{table_name_suffix}"
- end
-
def table_exists?
ActiveSupport::Deprecation.silence { connection.table_exists?(table_name) }
end
- def create_table(limit=nil)
+ def create_table
unless table_exists?
- version_options = {null: false}
- version_options[:limit] = limit if limit
+ version_options = connection.internal_string_options_for_primary_key
connection.create_table(table_name, id: false) do |t|
- t.column :version, :string, version_options
- t.index :version, unique: true, name: index_name
+ t.string :version, version_options
end
end
end
def drop_table
- if table_exists?
- connection.remove_index table_name, name: index_name
- connection.drop_table(table_name)
- end
+ connection.drop_table table_name, if_exists: true
end
def normalize_migration_number(number)
diff --git a/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb
index 107f107dc4..481c70201b 100644
--- a/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb
+++ b/activerecord/lib/rails/generators/active_record/migration/templates/migration.rb
@@ -19,7 +19,11 @@ class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Mi
def change
create_join_table :<%= join_tables.first %>, :<%= join_tables.second %> do |t|
<%- attributes.each do |attribute| -%>
+ <%- if attribute.reference? -%>
+ t.references :<%= attribute.name %><%= attribute.inject_options %>
+ <%- else -%>
<%= '# ' unless attribute.has_index? -%>t.index <%= attribute.index_name %><%= attribute.inject_index_options %>
+ <%- end -%>
<%- end -%>
end
end
diff --git a/activerecord/test/cases/adapters/mysql2/enum_test.rb b/activerecord/test/cases/adapters/mysql2/enum_test.rb
index bb89e893e0..35dbc76d1b 100644
--- a/activerecord/test/cases/adapters/mysql2/enum_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/enum_test.rb
@@ -18,4 +18,9 @@ class Mysql2EnumTest < ActiveRecord::Mysql2TestCase
column = EnumTest.columns_hash['enum_column']
assert_not column.unsigned?
end
+
+ def test_should_not_be_bigint
+ column = EnumTest.columns_hash['enum_column']
+ assert_not column.bigint?
+ end
end
diff --git a/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb b/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb
index 9a9a4fed42..7c89fda582 100644
--- a/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb
@@ -33,11 +33,6 @@ class SchemaMigrationsTest < ActiveRecord::Mysql2TestCase
end
end
- def test_key_limit_max_matches_max
- assert_equal ActiveRecord::InternalMetadata::KEY_LIMIT ,ActiveRecord::ConnectionAdapters::Mysql2Adapter::MAX_INDEX_LENGTH_FOR_CHARSETS_OF_4BYTES_MAXLEN
- end
-
-
private
def with_encoding_utf8mb4
diff --git a/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb b/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb
index b2a805333c..b56c226763 100644
--- a/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/extension_migration_test.rb
@@ -24,9 +24,9 @@ class PostgresqlExtensionMigrationTest < ActiveRecord::PostgreSQLTestCase
return skip("no extension support")
end
- @old_schema_migration_tabel_name = ActiveRecord::SchemaMigration.table_name
- @old_tabel_name_prefix = ActiveRecord::Base.table_name_prefix
- @old_tabel_name_suffix = ActiveRecord::Base.table_name_suffix
+ @old_schema_migration_table_name = ActiveRecord::SchemaMigration.table_name
+ @old_table_name_prefix = ActiveRecord::Base.table_name_prefix
+ @old_table_name_suffix = ActiveRecord::Base.table_name_suffix
ActiveRecord::Base.table_name_prefix = "p_"
ActiveRecord::Base.table_name_suffix = "_s"
@@ -36,11 +36,11 @@ class PostgresqlExtensionMigrationTest < ActiveRecord::PostgreSQLTestCase
end
def teardown
- ActiveRecord::Base.table_name_prefix = @old_tabel_name_prefix
- ActiveRecord::Base.table_name_suffix = @old_tabel_name_suffix
+ ActiveRecord::Base.table_name_prefix = @old_table_name_prefix
+ ActiveRecord::Base.table_name_suffix = @old_table_name_suffix
ActiveRecord::SchemaMigration.delete_all rescue nil
ActiveRecord::Migration.verbose = true
- ActiveRecord::SchemaMigration.table_name = @old_schema_migration_tabel_name
+ ActiveRecord::SchemaMigration.table_name = @old_schema_migration_table_name
super
end
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index f1995b243a..31e87722d9 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -53,12 +53,6 @@ module ActiveRecord
end
end
- def test_composite_primary_key
- with_example_table 'id serial, number serial, PRIMARY KEY (id, number)' do
- assert_nil @connection.primary_key('ex')
- end
- end
-
def test_primary_key_raises_error_if_table_not_found
assert_raises(ActiveRecord::StatementInvalid) do
@connection.primary_key('unobtainium')
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index 038d9e2d0f..02c3358ba6 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -400,12 +400,6 @@ module ActiveRecord
end
end
- def test_composite_primary_key
- with_example_table 'id integer, number integer, foo integer, PRIMARY KEY (id, number)' do
- assert_nil @conn.primary_key('ex')
- end
- end
-
def test_supports_extensions
assert_not @conn.supports_extensions?, 'does not support extensions'
end
diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb
index 1f32c48b95..9c99689c1e 100644
--- a/activerecord/test/cases/ar_schema_test.rb
+++ b/activerecord/test/cases/ar_schema_test.rb
@@ -21,7 +21,7 @@ if ActiveRecord::Base.connection.supports_migrations?
ActiveRecord::Migration.verbose = @original_verbose
end
- def test_has_has_primary_key
+ def test_has_primary_key
old_primary_key_prefix_type = ActiveRecord::Base.primary_key_prefix_type
ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore
assert_equal "version", ActiveRecord::SchemaMigration.primary_key
diff --git a/activerecord/test/cases/migration/compatibility_test.rb b/activerecord/test/cases/migration/compatibility_test.rb
index 6a9cdd9d29..6d5b6243db 100644
--- a/activerecord/test/cases/migration/compatibility_test.rb
+++ b/activerecord/test/cases/migration/compatibility_test.rb
@@ -71,6 +71,36 @@ module ActiveRecord
ensure
connection.drop_table :more_testings rescue nil
end
+
+ def test_timestamps_have_null_constraints_if_not_present_in_migration_of_create_table
+ migration = Class.new(ActiveRecord::Migration) {
+ def migrate(x)
+ create_table :more_testings do |t|
+ t.timestamps
+ end
+ end
+ }.new
+
+ ActiveRecord::Migrator.new(:up, [migration]).migrate
+
+ assert connection.columns(:more_testings).find { |c| c.name == 'created_at' }.null
+ assert connection.columns(:more_testings).find { |c| c.name == 'updated_at' }.null
+ ensure
+ connection.drop_table :more_testings rescue nil
+ end
+
+ def test_timestamps_have_null_constraints_if_not_present_in_migration_for_adding_timestamps_to_existing_table
+ migration = Class.new(ActiveRecord::Migration) {
+ def migrate(x)
+ add_timestamps :testings
+ end
+ }.new
+
+ ActiveRecord::Migrator.new(:up, [migration]).migrate
+
+ assert connection.columns(:testings).find { |c| c.name == 'created_at' }.null
+ assert connection.columns(:testings).find { |c| c.name == 'updated_at' }.null
+ end
end
end
end
diff --git a/activerecord/test/cases/migration/table_and_index_test.rb b/activerecord/test/cases/migration/table_and_index_test.rb
deleted file mode 100644
index 24cba84a09..0000000000
--- a/activerecord/test/cases/migration/table_and_index_test.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-require "cases/helper"
-
-module ActiveRecord
- class Migration
- class TableAndIndexTest < ActiveRecord::TestCase
- def test_add_schema_info_respects_prefix_and_suffix
- conn = ActiveRecord::Base.connection
-
- conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name, if_exists: true)
- # Use shorter prefix and suffix as in Oracle database identifier cannot be larger than 30 characters
- ActiveRecord::Base.table_name_prefix = 'p_'
- ActiveRecord::Base.table_name_suffix = '_s'
- conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name, if_exists: true)
-
- conn.initialize_schema_migrations_table
-
- assert_equal "p_unique_schema_migrations_s", conn.indexes(ActiveRecord::Migrator.schema_migrations_table_name)[0][:name]
- ensure
- ActiveRecord::Base.table_name_prefix = ""
- ActiveRecord::Base.table_name_suffix = ""
- end
- end
- end
-end
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 7e18313c00..b918b36b94 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -135,22 +135,20 @@ class PrimaryKeysTest < ActiveRecord::TestCase
end
end
- def test_primary_key_returns_value_if_it_exists
- klass = Class.new(ActiveRecord::Base) do
- self.table_name = 'developers'
- end
+ if ActiveRecord::Base.connection.supports_primary_key?
+ def test_primary_key_returns_value_if_it_exists
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = 'developers'
+ end
- if ActiveRecord::Base.connection.supports_primary_key?
assert_equal 'id', klass.primary_key
end
- end
- def test_primary_key_returns_nil_if_it_does_not_exist
- klass = Class.new(ActiveRecord::Base) do
- self.table_name = 'developers_projects'
- end
+ def test_primary_key_returns_nil_if_it_does_not_exist
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = 'developers_projects'
+ end
- if ActiveRecord::Base.connection.supports_primary_key?
assert_nil klass.primary_key
end
end
@@ -262,6 +260,13 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase
assert_equal ["region", "code"], @connection.primary_keys("barcodes")
end
+ def test_primary_key_issues_warning
+ warning = capture(:stderr) do
+ assert_nil @connection.primary_key("barcodes")
+ end
+ assert_match(/WARNING: Rails does not support composite primary key\./, warning)
+ end
+
def test_collectly_dump_composite_primary_key
schema = dump_table_schema "barcodes"
assert_match %r{create_table "barcodes", primary_key: \["region", "code"\]}, schema
diff --git a/activerecord/test/schema/mysql2_specific_schema.rb b/activerecord/test/schema/mysql2_specific_schema.rb
index 701e6f45b3..101e657982 100644
--- a/activerecord/test/schema/mysql2_specific_schema.rb
+++ b/activerecord/test/schema/mysql2_specific_schema.rb
@@ -21,16 +21,15 @@ ActiveRecord::Schema.define do
t.index :var_binary
end
- create_table :key_tests, force: true, :options => 'ENGINE=MyISAM' do |t|
+ create_table :key_tests, force: true, options: 'ENGINE=MyISAM' do |t|
t.string :awesome
t.string :pizza
t.string :snacks
+ t.index :awesome, type: :fulltext, name: 'index_key_tests_on_awesome'
+ t.index :pizza, using: :btree, name: 'index_key_tests_on_pizza'
+ t.index :snacks, name: 'index_key_tests_on_snack'
end
- add_index :key_tests, :awesome, :type => :fulltext, :name => 'index_key_tests_on_awesome'
- add_index :key_tests, :pizza, :using => :btree, :name => 'index_key_tests_on_pizza'
- add_index :key_tests, :snacks, :name => 'index_key_tests_on_snack'
-
create_table :collation_tests, id: false, force: true do |t|
t.string :string_cs_column, limit: 1, collation: 'utf8_bin'
t.string :string_ci_column, limit: 1, collation: 'utf8_general_ci'
@@ -62,7 +61,7 @@ SQL
ActiveRecord::Base.connection.execute <<-SQL
CREATE TABLE enum_tests (
- enum_column ENUM('text','blob','tiny','medium','long','unsigned')
+ enum_column ENUM('text','blob','tiny','medium','long','unsigned','bigint')
)
SQL
end
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index fcc4eee79c..b9e0706d60 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -202,12 +202,11 @@ ActiveRecord::Schema.define do
t.integer :rating, default: 1
t.integer :account_id
t.string :description, default: ""
+ t.index [:firm_id, :type, :rating], name: "company_index"
+ t.index [:firm_id, :type], name: "company_partial_index", where: "rating > 10"
+ t.index :name, name: 'company_name_index', using: :btree
end
- add_index :companies, [:firm_id, :type, :rating], name: "company_index"
- add_index :companies, [:firm_id, :type], name: "company_partial_index", where: "rating > 10"
- add_index :companies, :name, name: 'company_name_index', using: :btree
-
create_table :content, force: true do |t|
t.string :title
end
@@ -304,8 +303,8 @@ ActiveRecord::Schema.define do
create_table :edges, force: true, id: false do |t|
t.column :source_id, :integer, null: false
t.column :sink_id, :integer, null: false
+ t.index [:source_id, :sink_id], unique: true, name: 'unique_edge_index'
end
- add_index :edges, [:source_id, :sink_id], unique: true, name: 'unique_edge_index'
create_table :engines, force: true do |t|
t.integer :car_id
@@ -782,8 +781,8 @@ ActiveRecord::Schema.define do
t.string :nick, null: false
t.string :name
t.column :books_count, :integer, null: false, default: 0
+ t.index :nick, unique: true
end
- add_index :subscribers, :nick, unique: true
create_table :subscriptions, force: true do |t|
t.string :subscriber_id
diff --git a/activesupport/Rakefile b/activesupport/Rakefile
index 81c242d4b1..33ee62aa1b 100644
--- a/activesupport/Rakefile
+++ b/activesupport/Rakefile
@@ -1,6 +1,10 @@
require 'rake/testtask'
task :default => :test
+
+task :package
+task "package:clean"
+
Rake::TestTask.new do |t|
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
diff --git a/guides/bug_report_templates/generic_master.rb b/guides/bug_report_templates/generic_master.rb
index 0a8048cc48..fcc90fa503 100644
--- a/guides/bug_report_templates/generic_master.rb
+++ b/guides/bug_report_templates/generic_master.rb
@@ -19,9 +19,6 @@ require 'active_support'
require 'active_support/core_ext/object/blank'
require 'minitest/autorun'
-# Ensure backward compatibility with Minitest 4
-Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)
-
class BugTest < Minitest::Test
def test_stuff
assert "zomg".present?
diff --git a/guides/source/api_app.md b/guides/source/api_app.md
index e3481ce046..64b6bb64f2 100644
--- a/guides/source/api_app.md
+++ b/guides/source/api_app.md
@@ -262,9 +262,6 @@ subsequent inbound requests for the same URL.
Think of it as page caching using HTTP semantics.
-NOTE: This middleware is always outside of the `Rack::Lock` mutex, even in
-single-threaded applications.
-
### Using Rack::Sendfile
When you use the `send_file` method inside a Rails controller, it sets the
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index 5bdaf600ad..439f2bef3a 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -1177,19 +1177,14 @@ TIP: For further details have a look at the docs of your production web server:
Assets Cache Store
------------------
-The default Rails cache store will be used by Sprockets to cache assets in
-development and production. This can be changed by setting
-`config.assets.cache_store`:
+By default, Sprockets caches assets in `tmp/cache/assets` in development
+and production environments. This can be changed as follows:
```ruby
-config.assets.cache_store = :memory_store
-```
-
-The options accepted by the assets cache store are the same as the application's
-cache store.
-
-```ruby
-config.assets.cache_store = :memory_store, { size: 32.megabytes }
+config.assets.configure do |env|
+ env.cache = ActiveSupport::Cache.lookup_store(:memory_store,
+ { size: 32.megabytes })
+end
```
To disable the assets cache store:
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index f33e729de0..e25992fdef 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -432,7 +432,7 @@ Ruby version 2.2.2 (x86_64-linux)
RubyGems version 2.4.6
Rack version 1.6
JavaScript Runtime Node.js (V8)
-Middleware Rack::Sendfile, ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
+Middleware Rack::Sendfile, ActionDispatch::Static, ActionDispatch::LoadInterlock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
Application root /home/foobar/commandsapp
Environment development
Database adapter sqlite3
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 8a21d4062a..d9c345fb71 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -159,8 +159,6 @@ pipeline is enabled. It is set to true by default.
* `config.assets.debug` disables the concatenation and compression of assets. Set to `true` by default in `development.rb`.
-* `config.assets.cache_store` defines the cache store that Sprockets will use. The default is the Rails file store.
-
* `config.assets.compile` is a boolean that can be used to turn on live Sprockets compilation in production.
* `config.assets.logger` accepts a logger conforming to the interface of Log4r or the default Ruby `Logger` class. Defaults to the same configured at `config.logger`. Setting `config.assets.logger` to false will turn off served assets logging.
@@ -200,7 +198,7 @@ Every Rails application comes with a standard set of middleware which it uses in
* `ActionDispatch::SSL` forces every request to be served using HTTPS. Enabled if `config.force_ssl` is set to `true`. Options passed to this can be configured by setting `config.ssl_options`.
* `ActionDispatch::Static` is used to serve static assets. Disabled if `config.public_file_server.enabled` is `false`. Set `config.public_file_server.index_name` if you need to serve a static directory index file that is not named `index`. For example, to serve `main.html` instead of `index.html` for directory requests, set `config.public_file_server.index_name` to `"main"`.
-* `Rack::Lock` wraps the app in mutex so it can only be called by a single thread at a time. Only enabled when `config.cache_classes` is `false`.
+* `ActionDispatch::LoadInterlock` allows thread safe code reloading. Disabled if `config.allow_concurrency` is `false`, which causes `Rack::Lock` to be loaded. `Rack::Lock` wraps the app in mutex so it can only be called by a single thread at a time.
* `ActiveSupport::Cache::Strategy::LocalCache` serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread.
* `Rack::Runtime` sets an `X-Runtime` header, containing the time (in seconds) taken to execute the request.
* `Rails::Rack::Logger` notifies the logs that the request has begun. After request is complete, flushes all the logs.
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index cbc304c87f..f02f6a18ee 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -159,7 +159,7 @@ If you want to translate the Rails guides in your own language, follows these st
* Copy the contents of *guides/source* into your own language directory and translate them.
* Do NOT translate the HTML files, as they are automatically generated.
-To generate the guides in HTML format cd into the *guides* direcotry then run (eg. for it-IT):
+To generate the guides in HTML format cd into the *guides* directory then run (eg. for it-IT):
```bash
$ bundle install
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index 934693252e..3b61d65df5 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -104,7 +104,7 @@ For a freshly generated Rails application, this might produce something like:
```ruby
use Rack::Sendfile
use ActionDispatch::Static
-use Rack::Lock
+use ActionDispatch::LoadInterlock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x000000029a0838>
use Rack::Runtime
use Rack::MethodOverride
@@ -171,10 +171,10 @@ Add the following lines to your application configuration:
```ruby
# config/application.rb
-config.middleware.delete Rack::Lock
+config.middleware.delete Rack::Runtime
```
-And now if you inspect the middleware stack, you'll find that `Rack::Lock` is
+And now if you inspect the middleware stack, you'll find that `Rack::Runtime` is
not a part of it.
```bash
@@ -219,6 +219,10 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol
* Sets `env["rack.multithread"]` flag to `false` and wraps the application within a Mutex.
+**`ActionDispatch::LoadInterlock`**
+
+* Used for thread safe code reloading during development.
+
**`ActiveSupport::Cache::Strategy::LocalCache::Middleware`**
* Used for memory caching. This cache is not thread safe.
diff --git a/guides/source/testing.md b/guides/source/testing.md
index b5e49a41f4..f4894d4c11 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -638,9 +638,9 @@ We were able to successfully test a very small workflow for visiting our blog an
Functional Tests for Your Controllers
-------------------------------------
-In Rails, testing the various actions of a controller is a form of writing functional tests. Remember your controllers handle the incoming web requests to your application and eventually respond with a rendered view. When writing functional tests, you're testing how your actions handle the requests and the expected result, or response in some cases an HTML view.
+In Rails, testing the various actions of a controller is a form of writing functional tests. Remember your controllers handle the incoming web requests to your application and eventually respond with a rendered view. When writing functional tests, you are testing how your actions handle the requests and the expected result or response, in some cases an HTML view.
-### What to Include in your Functional Tests
+### What to include in your Functional Tests
You should test for things such as:
@@ -650,8 +650,7 @@ You should test for things such as:
* was the correct object stored in the response template?
* was the appropriate message displayed to the user in the view?
-The easiest way to see functional tests in action is to generate a controller
-scaffold:
+The easiest way to see functional tests in action is to generate a controller using the scaffold generator:
```bash
$ bin/rails generate scaffold_controller article title:string body:text
@@ -664,7 +663,7 @@ create test/controllers/articles_controller_test.rb
```
This will generate the controller code and tests for an `Article` resource.
-You can take look at the file `articles_controller_test.rb` in the `test/controllers` directory.
+You can take a look at the file `articles_controller_test.rb` in the `test/controllers` directory.
If you already have a controller and just want to generate the test scaffold code for
each of the seven default actions, you can use the following command:
@@ -677,7 +676,7 @@ create test/controllers/articles_controller_test.rb
...
```
-Let me take you through one such test, `test_should_get_index` from the file `articles_controller_test.rb`.
+Let's take a look at one such test, `test_should_get_index` from the file `articles_controller_test.rb`.
```ruby
# articles_controller_test.rb
@@ -693,7 +692,7 @@ end
In the `test_should_get_index` test, Rails simulates a request on the action called `index`, making sure the request was successful
and also ensuring that the right response body has been generated.
-The `get` method kicks off the web request and populates the results into the response. It accepts 4 arguments:
+The `get` method kicks off the web request and populates the results into the `@response`. It accepts 4 arguments:
* The action of the controller you are requesting.
This can be in the form of a string or a route (i.e. `articles_url`).
@@ -705,7 +704,7 @@ The `get` method kicks off the web request and populates the results into the re
* `flash`: option with a hash of flash values.
-All the keyword arguments are optional.
+All of these keyword arguments are optional.
Example: Calling the `:show` action, passing an `id` of 12 as the `params` and setting a `user_id` of 5 in the session:
@@ -753,7 +752,7 @@ NOTE: Functional tests do not verify whether the specified request type is accep
### Testing XHR (AJAX) requests
To test AJAX requests, you can specify the `xhr: true` option to `get`, `post`,
-`patch`, `put`, and `delete` methods:
+`patch`, `put`, and `delete` methods. For example:
```ruby
test "ajax request" do
@@ -808,7 +807,7 @@ post article_url # simulate the request with custom env variable
### Testing `flash` notices
-If you remember from earlier one of the Three Hashes of the Apocalypse was `flash`.
+If you remember from earlier, one of the Three Hashes of the Apocalypse was `flash`.
We want to add a `flash` message to our blog application whenever someone
successfully creates a new Article.
@@ -893,7 +892,7 @@ test "should show article" do
end
```
-Remember from our discussion earlier on fixtures the `articles()` method will give us access to our Articles fixtures.
+Remember from our discussion earlier on fixtures, the `articles()` method will give us access to our Articles fixtures.
How about deleting an existing Article?
@@ -913,14 +912,19 @@ We can also add a test for updating an existing Article.
```ruby
test "should update article" do
article = articles(:one)
+
patch '/article', params: { id: article.id, article: { title: "updated" } }
+
assert_redirected_to article_path(article)
+ # Reload association to fetch updated data and assert that title is updated.
+ article.reload
+ assert_equal "updated", article.title
end
```
Notice we're starting to see some duplication in these three tests, they both access the same Article fixture data. We can D.R.Y. this up by using the `setup` and `teardown` methods provided by `ActiveSupport::Callbacks`.
-Our test should now look something like this, disregard the other tests we're leaving them out for brevity.
+Our test should now look something as what follows. Disregard the other tests for now, we're leaving them out for brevity.
```ruby
require 'test_helper'
@@ -952,8 +956,12 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest
end
test "should update article" do
- patch article_url(@article), params: { article: { title: "updated" } }
+ patch '/article', params: { id: @article.id, article: { title: "updated" } }
+
assert_redirected_to article_path(@article)
+ # Reload association to fetch updated data and assert that title is updated.
+ @article.reload
+ assert_equal "updated", @article.title
end
end
```
@@ -966,7 +974,7 @@ To avoid code duplication, you can add your own test helpers.
Sign in helper can be a good example:
```ruby
-test/test_helper.rb
+#test/test_helper.rb
module SignInHelper
def sign_in(user)
@@ -1087,8 +1095,9 @@ have to use a mixin like this:
```ruby
class UserHelperTest < ActionView::TestCase
- test "should return the user name" do
- # ...
+ test "should return the user's full name" do
+ user = users(:david)
+ assert_equal "David Heinemeier Hansson", user_full_name(user)
end
end
```
@@ -1123,7 +1132,7 @@ In order to test that your mailer is working as expected, you can use unit tests
For the purposes of unit testing a mailer, fixtures are used to provide an example of how the output _should_ look. Because these are example emails, and not Active Record data like the other fixtures, they are kept in their own subdirectory apart from the other fixtures. The name of the directory within `test/fixtures` directly corresponds to the name of the mailer. So, for a mailer named `UserMailer`, the fixtures should reside in `test/fixtures/user_mailer` directory.
-When you generated your mailer, the generator creates stub fixtures for each of the mailers actions. If you didn't use the generator you'll have to make those files yourself.
+When you generated your mailer, the generator creates stub fixtures for each of the mailers actions. If you didn't use the generator, you'll have to create those files yourself.
#### The Basic Test Case
@@ -1204,7 +1213,7 @@ Testing Jobs
------------
Since your custom jobs can be queued at different levels inside your application,
-you'll need to test both jobs themselves (their behavior when they get enqueued)
+you'll need to test both, the jobs themselves (their behavior when they get enqueued)
and that other entities correctly enqueue them.
### A Basic Test Case
@@ -1255,7 +1264,7 @@ end
Testing Time-Dependent Code
---------------------------
-Rails provides inbuilt helper methods that enable you to assert that your time-sensitve code works as expected.
+Rails provides built-in helper methods that enable you to assert that your time-sensitive code works as expected.
Here is an example using the [`travel_to`](http://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html#method-i-travel_to) helper:
diff --git a/railties/Rakefile b/railties/Rakefile
index cf130a5f14..3421d9b464 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -2,6 +2,9 @@ require 'rake/testtask'
task :default => :test
+task :package
+task "package:clean"
+
desc "Run all unit tests"
task :test => 'test:isolated'
diff --git a/railties/lib/rails/engine/commands.rb b/railties/lib/rails/engine/commands.rb
index a6d87b78e4..7bbd9ef744 100644
--- a/railties/lib/rails/engine/commands.rb
+++ b/railties/lib/rails/engine/commands.rb
@@ -1,3 +1,5 @@
+require 'rails/engine/commands_tasks'
+
ARGV << '--help' if ARGV.empty?
aliases = {
@@ -9,35 +11,4 @@ aliases = {
command = ARGV.shift
command = aliases[command] || command
-require ENGINE_PATH
-engine = ::Rails::Engine.find(ENGINE_ROOT)
-
-case command
-when 'generate', 'destroy', 'test'
- require 'rails/generators'
- Rails::Generators.namespace = engine.railtie_namespace
- engine.load_generators
- require "rails/commands/#{command}"
-
-when '--version', '-v'
- ARGV.unshift '--version'
- require 'rails/commands/application'
-
-else
- puts "Error: Command not recognized" unless %w(-h --help).include?(command)
- puts <<-EOT
-Usage: rails COMMAND [ARGS]
-
-The common Rails commands available for engines are:
- generate Generate new code (short-cut alias: "g")
- destroy Undo code generated with "generate" (short-cut alias: "d")
- test Run tests (short-cut alias: "t")
-
-All commands can be run with -h for more information.
-
-If you want to run any commands that need to be run in context
-of the application, like `rails server` or `rails console`,
-you should do it from application's directory (typically test/dummy).
- EOT
- exit(1)
-end
+Rails::Engine::CommandsTasks.new(ARGV).run_command!(command)
diff --git a/railties/lib/rails/engine/commands_tasks.rb b/railties/lib/rails/engine/commands_tasks.rb
new file mode 100644
index 0000000000..fa3ee59b7d
--- /dev/null
+++ b/railties/lib/rails/engine/commands_tasks.rb
@@ -0,0 +1,116 @@
+require 'rails/commands/rake_proxy'
+
+module Rails
+ class Engine
+ class CommandsTasks # :nodoc:
+ include Rails::RakeProxy
+
+ attr_reader :argv
+
+ HELP_MESSAGE = <<-EOT
+Usage: rails COMMAND [ARGS]
+
+The common Rails commands available for engines are:
+ generate Generate new code (short-cut alias: "g")
+ destroy Undo code generated with "generate" (short-cut alias: "d")
+ test Run tests (short-cut alias: "t")
+
+All commands can be run with -h for more information.
+
+If you want to run any commands that need to be run in context
+of the application, like `rails server` or `rails console`,
+you should do it from application's directory (typically test/dummy).
+
+In addition to those commands, there are:
+ EOT
+
+ COMMAND_WHITELIST = %w(generate destroy version help test)
+
+ def initialize(argv)
+ @argv = argv
+ end
+
+ def run_command!(command)
+ command = parse_command(command)
+
+ if COMMAND_WHITELIST.include?(command)
+ send(command)
+ else
+ run_rake_task(command)
+ end
+ end
+
+ def generate
+ generate_or_destroy(:generate)
+ end
+
+ def destroy
+ generate_or_destroy(:destroy)
+ end
+
+ def test
+ require_command!("test")
+ end
+
+ def version
+ argv.unshift '--version'
+ require_command!("application")
+ end
+
+ def help
+ write_help_message
+ write_commands(formatted_rake_tasks)
+ end
+
+ private
+
+ def require_command!(command)
+ require "rails/commands/#{command}"
+ end
+
+ def generate_or_destroy(command)
+ load_generators
+ require_command!(command)
+ end
+
+ def load_generators
+ require 'rails/generators'
+ require ENGINE_PATH
+
+ engine = ::Rails::Engine.find(ENGINE_ROOT)
+ Rails::Generators.namespace = engine.railtie_namespace
+ engine.load_generators
+ end
+
+ def write_help_message
+ puts HELP_MESSAGE
+ end
+
+ def write_commands(commands)
+ width = commands.map { |name, _| name.size }.max || 10
+ commands.each { |command| printf(" %-#{width}s %s\n", *command) }
+ end
+
+ def parse_command(command)
+ case command
+ when '--version', '-v'
+ 'version'
+ when '--help', '-h'
+ 'help'
+ else
+ command
+ end
+ end
+
+ def rake_tasks
+ return @rake_tasks if defined?(@rake_tasks)
+
+ load_generators
+ Rake::TaskManager.record_task_metadata = true
+ Rake.application.init('rails')
+ Rake.application.load_rakefile
+ @rake_tasks = Rake.application.tasks.select(&:comment)
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index a4758857f2..775750d86b 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -318,7 +318,6 @@ module Rails
remove_file 'config/cable.yml'
remove_file 'app/assets/javascripts/cable.coffee'
remove_dir 'app/channels'
- gsub_file 'app/views/layouts/application.html.erb', /action_cable_meta_tag/, '' unless options[:api]
end
end
diff --git a/railties/lib/rails/tasks/engine.rake b/railties/lib/rails/tasks/engine.rake
index c51524f8f6..e678103f63 100644
--- a/railties/lib/rails/tasks/engine.rake
+++ b/railties/lib/rails/tasks/engine.rake
@@ -4,8 +4,8 @@ task "load_app" do
end
task :environment => "app:environment"
- if !defined?(ENGINE_PATH) || !ENGINE_PATH
- ENGINE_PATH = find_engine_path(APP_RAKEFILE)
+ if !defined?(ENGINE_ROOT) || !ENGINE_ROOT
+ ENGINE_ROOT = find_engine_path(APP_RAKEFILE)
end
end
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index ef33cd4ff7..0fd1d34131 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -240,7 +240,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
run_generator [destination_root, "--mountable"]
FileUtils.cd destination_root
quietly { system 'bundle install' }
- output = `bundle exec rake db:migrate 2>&1`
+ output = `bin/rails db:migrate 2>&1`
assert $?.success?, "Command failed: #{output}"
end
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index 6f7a83cae0..5e45120704 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -486,7 +486,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
Dir.chdir(engine_path) do
quietly do
`bin/rails g scaffold User name:string age:integer;
- bundle exec rake db:migrate`
+ bin/rails db:migrate`
end
assert_match(/8 runs, 13 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
end
@@ -500,7 +500,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
Dir.chdir(engine_path) do
quietly do
`bin/rails g scaffold User name:string age:integer;
- bundle exec rake db:migrate`
+ bin/rails db:migrate`
end
assert_match(/8 runs, 13 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
end
@@ -514,7 +514,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
Dir.chdir(engine_path) do
quietly do
`bin/rails g scaffold User name:string age:integer;
- bundle exec rake db:migrate`
+ bin/rails db:migrate`
end
assert_match(/6 runs, 8 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
end
@@ -528,7 +528,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
Dir.chdir(engine_path) do
quietly do
`bin/rails g scaffold User name:string age:integer;
- bundle exec rake db:migrate`
+ bin/rails db:migrate`
end
assert_match(/6 runs, 8 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
end
diff --git a/tasks/release.rb b/tasks/release.rb
index c7704aa865..de9c51a140 100644
--- a/tasks/release.rb
+++ b/tasks/release.rb
@@ -13,6 +13,7 @@ directory "pkg"
task :clean do
rm_f gem
+ sh "cd #{framework} && bundle exec rake package:clean" unless framework == "rails"
end
task :update_versions do
@@ -48,6 +49,7 @@ directory "pkg"
task gem => %w(update_versions pkg) do
cmd = ""
cmd << "cd #{framework} && " unless framework == "rails"
+ cmd << "bundle exec rake package && " unless framework == "rails"
cmd << "gem build #{gemspec} && mv #{framework}-#{version}.gem #{root}/pkg/"
sh cmd
end