aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--Gemfile.lock1
-rw-r--r--actioncable/.gitignore2
-rw-r--r--actioncable/Rakefile44
-rw-r--r--actioncable/actioncable.gemspec8
-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--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/persistence.rb6
-rw-r--r--activerecord/lib/active_record/railtie.rb2
-rw-r--r--activerecord/lib/active_record/reflection.rb68
-rw-r--r--activesupport/Rakefile4
-rw-r--r--guides/bug_report_templates/generic_master.rb3
-rw-r--r--guides/source/active_record_basics.md102
-rw-r--r--guides/source/api_app.md3
-rw-r--r--guides/source/command_line.md2
-rw-r--r--guides/source/configuring.md2
-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/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
38 files changed, 394 insertions, 123 deletions
diff --git a/.travis.yml b/.travis.yml
index 869507a9fd..ae38617b99 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,7 +30,6 @@ rvm:
matrix:
allow_failures:
- rvm: ruby-head
- - env: "GEM=ac"
fast_finish: true
notifications:
email: false
diff --git a/Gemfile.lock b/Gemfile.lock
index d2d616b39d..1da3926dd0 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..8d35d819cf 100644
--- a/actioncable/actioncable.gemspec
+++ b/actioncable/actioncable.gemspec
@@ -20,13 +20,15 @@ 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 'coffee-script', '~> 2.4.1'
+ s.add_development_dependency 'coffee-script-source', '~> 1.10.0'
+ 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'
+ s.add_development_dependency 'redis', '~> 3.0'
+ s.add_development_dependency 'sprockets', '~> 3.5.2'
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/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/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/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/active_record_basics.md b/guides/source/active_record_basics.md
index fba89f9d13..0932cc4829 100644
--- a/guides/source/active_record_basics.md
+++ b/guides/source/active_record_basics.md
@@ -375,3 +375,105 @@ and to roll it back, `rails db:rollback`.
Note that the above code is database-agnostic: it will run in MySQL,
PostgreSQL, Oracle and others. You can learn more about migrations in the
[Active Record Migrations guide](migrations.html).
+
+Connecting to the Database
+----------------------
+
+### `config/database.yml`
+
+When managing connections to the database, the `config/database.yml` file is
+your best friend. This file helps to keep track of the adapter and
+authentication parameters you are using for every database
+environment in your application. This file is automatically
+generated in all new Rails applications that have Active Record
+enabled.
+
+Here's an example of what this file looks like:
+
+```yaml
+default: &default
+ adapter: sqlite3
+ pool: 5
+ timeout: 5000
+
+development:
+ <<: *default
+ database: db/development.sqlite3
+
+test:
+ <<: *default
+ database: db/test.sqlite3
+
+production:
+ <<: *default
+ database: db/production.sqlite3
+```
+
+As you can see, there are 3 different database configurations listed
+above. One for each of the Rails environments for this application
+-- development, test, and production. As well, all three
+environments are sharing the same adapter, pool, and timeout
+settings, so this was extracted out to the "default" group. This
+extraction helps to keep your `config/database.yml` file DRY and easy
+to read.
+
+A small side note before the next topic -- the test database
+configured above will be deleted and restored both before and after
+every test run, so make sure you keep your environments' databases
+separated and siloed.
+
+### Connecting Manually
+
+In some special cases, you may want to establish connections for you
+Active Record models directly inside the model file itself. For this
+purpose, the `establish_connection` function was created. Say for
+example you have a `Message` model, like below:
+
+```ruby
+class Message < ActiveRecord::Base
+end
+```
+
+Also, say you want to have this `Message` model connect to a
+special "msg" database, instead of the one that the rest of the
+application is using. In this case, you would do as follows:
+
+Step 1: Add the `establish_connection` helper method to your model
+file:
+
+```ruby
+class Message < ActiveRecord::Base
+ establish_connection()
+end
+```
+
+Step 2: Add the configuration for this new database to your
+`config/database.yml` file, under the `msg` (or whichever name you
+choose) database name.
+
+Step 3: Turn this database name into a symbol. Remember, using string
+keys here is not supported! In this case, `msg`
+converts simply to `:msg`. If you are unsure of what the symbolized
+database name would be, simply boot up either an `irb` or `rails c`
+session, and type in the name of your database as a String, with a
+`.to_sym` at the end, as follows:
+
+```bash
+irb(main):001:0> "msg".to_sym
+=> :msg
+```
+
+Step 4: The last and final step! Simply use this symbolized
+database name as the sole parameter for the `establish_connection`
+method.
+
+```ruby
+class Message < ActiveRecord::Base
+ establish_connection(:msg)
+end
+```
+
+That's all there is to it! When configuring your database via the
+`config/database.yml` file, or connecting manually in your model,
+connecting to your database and making changes is easy when using Active
+Record.
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/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..91008ec3c9 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -200,7 +200,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/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