aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib/rails')
-rw-r--r--railties/lib/rails/application.rb42
-rw-r--r--railties/lib/rails/application/bootstrap.rb2
-rw-r--r--railties/lib/rails/application/configuration.rb6
-rw-r--r--railties/lib/rails/application/finisher.rb12
-rw-r--r--railties/lib/rails/application/routes_reloader.rb46
-rw-r--r--[-rwxr-xr-x]railties/lib/rails/commands/generate.rb0
-rw-r--r--railties/lib/rails/commands/runner.rb1
-rw-r--r--railties/lib/rails/commands/server.rb5
-rw-r--r--railties/lib/rails/console/app.rb2
-rw-r--r--railties/lib/rails/engine.rb29
-rw-r--r--railties/lib/rails/engine/configuration.rb10
-rw-r--r--railties/lib/rails/generators.rb3
-rw-r--r--railties/lib/rails/generators/actions.rb2
-rw-r--r--railties/lib/rails/generators/base.rb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb7
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb8
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb6
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb14
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/new.html.erb4
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/show.html.erb6
-rw-r--r--railties/lib/rails/generators/named_base.rb24
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/README8
-rw-r--r--[-rwxr-xr-x]railties/lib/rails/generators/rails/app/templates/Rakefile0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml60
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/routes.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js171
-rw-r--r--railties/lib/rails/generators/rails/model/USAGE2
-rw-r--r--railties/lib/rails/generators/rails/resource/resource_generator.rb18
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb58
-rw-r--r--railties/lib/rails/generators/resource_helpers.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/model/model_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb1
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb28
-rw-r--r--railties/lib/rails/initializable.rb19
-rw-r--r--railties/lib/rails/log_subscriber.rb115
-rw-r--r--railties/lib/rails/log_subscriber/test_helper.rb97
-rw-r--r--railties/lib/rails/paths.rb51
-rw-r--r--railties/lib/rails/plugin.rb16
-rw-r--r--railties/lib/rails/rack/logger.rb24
-rw-r--r--railties/lib/rails/railtie.rb34
-rw-r--r--railties/lib/rails/webrick_server.rb156
51 files changed, 388 insertions, 735 deletions
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 85ae8cbbb1..4a7ed2d028 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/hash/reverse_merge'
+require 'active_support/file_update_checker'
require 'fileutils'
require 'rails/plugin'
require 'rails/engine'
@@ -27,7 +28,7 @@ module Rails
# Besides providing the same configuration as Rails::Engine and Rails::Railtie,
# the application object has several specific configurations, for example
# "allow_concurrency", "cache_classes", "consider_all_requests_local", "filter_parameters",
- # "logger", "reload_engines", "reload_plugins" and so forth.
+ # "logger", "reload_plugins" and so forth.
#
# Check Rails::Application::Configuration to see them all.
#
@@ -46,7 +47,6 @@ module Rails
autoload :Configuration, 'rails/application/configuration'
autoload :Finisher, 'rails/application/finisher'
autoload :Railties, 'rails/application/railties'
- autoload :RoutesReloader, 'rails/application/routes_reloader'
class << self
private :new
@@ -67,7 +67,7 @@ module Rails
raise "You cannot have more than one Rails::Application" if Rails.application
super
Rails.application = base.instance
- Rails.application.add_lib_to_load_paths!
+ Rails.application.add_lib_to_load_path!
ActiveSupport.run_load_hooks(:before_configuration, base.instance)
end
@@ -84,17 +84,30 @@ module Rails
delegate :middleware, :to => :config
- def add_lib_to_load_paths!
+ # This method is called just after an application inherits from Rails::Application,
+ # allowing the developer to load classes in lib and use them during application
+ # configuration.
+ #
+ # class MyApplication < Rails::Application
+ # require "my_backend" # in lib/my_backend
+ # config.i18n.backend = MyBackend
+ # end
+ #
+ # Notice this method takes into consideration the default root path. So if you
+ # are changing config.root inside your application definition or having a custom
+ # Rails application, you will need to add lib to $LOAD_PATH on your own in case
+ # you need to load files in lib/ during the application configuration as well.
+ def add_lib_to_load_path! #:nodoc:
path = config.root.join('lib').to_s
$LOAD_PATH.unshift(path) if File.exists?(path)
end
- def require_environment!
+ def require_environment! #:nodoc:
environment = paths.config.environment.to_a.first
require environment if environment
end
- def eager_load!
+ def eager_load! #:nodoc:
railties.all(&:eager_load!)
super
end
@@ -108,11 +121,18 @@ module Rails
end
def routes_reloader
- @routes_reloader ||= RoutesReloader.new
+ @routes_reloader ||= ActiveSupport::FileUpdateChecker.new([]){ reload_routes! }
end
def reload_routes!
- routes_reloader.reload!
+ routes = Rails::Application.routes
+ routes.disable_clear_and_finalize = true
+
+ routes.clear!
+ routes_reloader.paths.each { |path| load(path) }
+ ActiveSupport.on_load(:action_controller) { routes.finalize! }
+ ensure
+ routes.disable_clear_and_finalize = false
end
def initialize!
@@ -140,6 +160,7 @@ module Rails
config.middleware.build(routes)
end
end
+ alias :build_middleware_stack :app
def call(env)
app.call(env.reverse_merge!(env_defaults))
@@ -196,10 +217,5 @@ module Rails
def initialize_generators
require "rails/generators"
end
-
- # Application is always reloadable when config.cache_classes is false.
- def reloadable?(app)
- true
- end
end
end
diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb
index 0a435f0f36..44e26b5713 100644
--- a/railties/lib/rails/application/bootstrap.rb
+++ b/railties/lib/rails/application/bootstrap.rb
@@ -1,4 +1,5 @@
require "active_support/notifications"
+require "active_support/descendants_tracker"
module Rails
class Application
@@ -55,6 +56,7 @@ module Rails
initializer :set_clear_dependencies_hook do
unless config.cache_classes
ActionDispatch::Callbacks.after do
+ ActiveSupport::DescendantsTracker.clear
ActiveSupport::Dependencies.clear
end
end
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 25e54e9dce..465851c0e6 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -10,7 +10,7 @@ module Rails
attr_accessor :allow_concurrency, :cache_classes, :cache_store,
:encoding, :consider_all_requests_local, :dependency_loading,
:filter_parameters, :log_level, :logger, :middleware,
- :plugins, :preload_frameworks, :reload_engines, :reload_plugins,
+ :plugins, :preload_frameworks, :reload_plugins,
:secret_token, :serve_static_assets, :session_options,
:time_zone, :whiny_nils
@@ -59,7 +59,7 @@ module Rails
if File.exists?("#{root}/test/mocks/#{Rails.env}")
ActiveSupport::Deprecation.warn "\"Rails.root/test/mocks/#{Rails.env}\" won't be added " <<
"automatically to load paths anymore in future releases"
- paths.mocks_path "test/mocks", :load_path => true, :glob => Rails.env
+ paths.mocks_path "test/mocks", :autoload => true, :glob => Rails.env
end
paths
@@ -110,7 +110,7 @@ module Rails
def colorize_logging=(val)
@colorize_logging = val
- Rails::LogSubscriber.colorize_logging = val
+ ActiveSupport::LogSubscriber.colorize_logging = val
self.generators.colorize_logging = val
end
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index d7ff489336..855467227b 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -7,14 +7,14 @@ module Rails
config.generators.templates.unshift(*paths.lib.templates.to_a)
end
- initializer :ensure_load_once_paths_as_subset do
- extra = ActiveSupport::Dependencies.load_once_paths -
- ActiveSupport::Dependencies.load_paths
+ initializer :ensure_autoload_once_paths_as_subset do
+ extra = ActiveSupport::Dependencies.autoload_once_paths -
+ ActiveSupport::Dependencies.autoload_paths
unless extra.empty?
abort <<-end_error
- load_once_paths must be a subset of the load_paths.
- Extra items in load_once_paths: #{extra * ','}
+ autoload_once_paths must be a subset of the autoload_paths.
+ Extra items in autoload_once_paths: #{extra * ','}
end_error
end
end
@@ -32,7 +32,7 @@ module Rails
end
initializer :build_middleware_stack do
- app
+ build_middleware_stack
end
initializer :eager_load! do
diff --git a/railties/lib/rails/application/routes_reloader.rb b/railties/lib/rails/application/routes_reloader.rb
deleted file mode 100644
index a2b3622df8..0000000000
--- a/railties/lib/rails/application/routes_reloader.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-module Rails
- class Application
- class RoutesReloader
- attr_reader :paths
-
- def initialize
- @paths, @last_change_at = [], nil
- end
-
- def changed_at
- routes_changed_at = nil
-
- paths.each do |path|
- config_changed_at = File.stat(path).mtime
-
- if routes_changed_at.nil? || config_changed_at > routes_changed_at
- routes_changed_at = config_changed_at
- end
- end
-
- routes_changed_at
- end
-
- def reload!
- routes = Rails::Application.routes
- routes.disable_clear_and_finalize = true
-
- routes.clear!
- paths.each { |path| load(path) }
- ActiveSupport.on_load(:action_controller) { routes.finalize! }
-
- nil
- ensure
- routes.disable_clear_and_finalize = false
- end
-
- def reload_if_changed
- current_change_at = changed_at
- if @last_change_at != current_change_at
- @last_change_at = current_change_at
- reload!
- end
- end
- end
- end
-end \ No newline at end of file
diff --git a/railties/lib/rails/commands/generate.rb b/railties/lib/rails/commands/generate.rb
index 1b3eef504a..1b3eef504a 100755..100644
--- a/railties/lib/rails/commands/generate.rb
+++ b/railties/lib/rails/commands/generate.rb
diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb
index 278548558e..b97ff086b6 100644
--- a/railties/lib/rails/commands/runner.rb
+++ b/railties/lib/rails/commands/runner.rb
@@ -44,6 +44,7 @@ begin
$stderr.puts "Run '#{$0} -h' for help."
exit 1
elsif File.exist?(code_or_file)
+ $0 = code_or_file
eval(File.read(code_or_file), nil, code_or_file)
else
eval(code_or_file)
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 3f74cd49fc..9d9dd48ea9 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -9,7 +9,7 @@ module Rails
args, options = args.dup, {}
opt_parser = OptionParser.new do |opts|
- opts.banner = "Usage: rails server [options]"
+ opts.banner = "Usage: rails server [mongrel, thin, etc] [options]"
opts.on("-p", "--port=port", Integer,
"Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v }
opts.on("-b", "--binding=ip", String,
@@ -83,7 +83,8 @@ module Rails
:environment => (ENV['RAILS_ENV'] || "development").dup,
:daemonize => false,
:debugger => false,
- :pid => "tmp/pids/server.pid"
+ :pid => File.expand_path("tmp/pids/server.pid"),
+ :config => File.expand_path("config.ru")
})
end
end
diff --git a/railties/lib/rails/console/app.rb b/railties/lib/rails/console/app.rb
index 4a7701081b..9d9763699d 100644
--- a/railties/lib/rails/console/app.rb
+++ b/railties/lib/rails/console/app.rb
@@ -30,5 +30,3 @@ def reload!(print=true)
ActionDispatch::Callbacks.new(Proc.new {}, false).call({})
true
end
-
-reload!(false)
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index cdb00a4eff..ee3e3ba040 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -32,14 +32,14 @@ module Rails
# == Configuration
#
# Besides the Railtie configuration which is shared across the application, in a
- # Rails::Engine you can access load_paths, eager_load_paths and load_once_paths,
+ # Rails::Engine you can access autoload_paths, eager_load_paths and autoload_once_paths,
# which differently from a Railtie, are scoped to the current Engine.
#
# Example:
#
# class MyEngine < Rails::Engine
# # Add a load path for this specific Engine
- # config.load_paths << File.expand_path("../lib/some/path", __FILE__)
+ # config.autoload_paths << File.expand_path("../lib/some/path", __FILE__)
#
# initializer "my_engine.add_middleware" do |app|
# app.middleware.use MyEngine::Middleware
@@ -142,7 +142,7 @@ module Rails
# Add configured load paths to ruby load paths and remove duplicates.
initializer :set_load_path, :before => :bootstrap_hook do
- config.load_paths.reverse_each do |path|
+ _all_load_paths.reverse_each do |path|
$LOAD_PATH.unshift(path) if File.directory?(path)
end
$LOAD_PATH.uniq!
@@ -154,17 +154,13 @@ module Rails
# This needs to be an initializer, since it needs to run once
# per engine and get the engine as a block parameter
initializer :set_autoload_paths, :before => :bootstrap_hook do |app|
- ActiveSupport::Dependencies.load_paths.unshift(*config.load_paths)
-
- if reloadable?(app)
- ActiveSupport::Dependencies.load_once_paths.unshift(*config.load_once_paths)
- else
- ActiveSupport::Dependencies.load_once_paths.unshift(*config.load_paths)
- end
+ ActiveSupport::Dependencies.autoload_paths.unshift(*_all_autoload_paths)
+ ActiveSupport::Dependencies.autoload_once_paths.unshift(*config.autoload_once_paths)
# Freeze so future modifications will fail rather than do nothing mysteriously
- config.load_paths.freeze
- config.load_once_paths.freeze
+ config.autoload_paths.freeze
+ config.eager_load_paths.freeze
+ config.autoload_once_paths.freeze
end
initializer :add_routing_paths do |app|
@@ -195,7 +191,6 @@ module Rails
ActiveSupport.on_load(:action_controller) do
prepend_view_path(views)
end
-
ActiveSupport.on_load(:action_mailer) do
prepend_view_path(views)
end
@@ -214,8 +209,12 @@ module Rails
protected
- def reloadable?(app)
- app.config.reload_engines
+ def _all_autoload_paths
+ @_all_autoload_paths ||= (config.autoload_paths + config.eager_load_paths + config.autoload_once_paths).uniq
+ end
+
+ def _all_load_paths
+ @_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq
end
end
end
diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
index 446fe0bda9..2f465670cf 100644
--- a/railties/lib/rails/engine/configuration.rb
+++ b/railties/lib/rails/engine/configuration.rb
@@ -4,7 +4,7 @@ module Rails
class Engine
class Configuration < ::Rails::Railtie::Configuration
attr_reader :root
- attr_writer :eager_load_paths, :load_once_paths, :load_paths
+ attr_writer :eager_load_paths, :autoload_once_paths, :autoload_paths
def initialize(root=nil)
super()
@@ -41,12 +41,12 @@ module Rails
@eager_load_paths ||= paths.eager_load
end
- def load_once_paths
- @load_once_paths ||= paths.load_once
+ def autoload_once_paths
+ @autoload_once_paths ||= paths.autoload_once
end
- def load_paths
- @load_paths ||= paths.load_paths
+ def autoload_paths
+ @autoload_paths ||= paths.autoload_paths
end
end
end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 41aecea355..8794392a7d 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -50,7 +50,6 @@ module Rails
:performance_tool => nil,
:resource_controller => :controller,
:scaffold_controller => :scaffold_controller,
- :singleton => false,
:stylesheets => true,
:test_framework => nil,
:template_engine => :erb
@@ -334,4 +333,4 @@ module Rails
paths
end
end
-end \ No newline at end of file
+end
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index 7af329bbf0..199afbdc30 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -275,7 +275,7 @@ module Rails
#
def route(routing_code)
log :route, routing_code
- sentinel = "routes.draw do |map|"
+ sentinel = /\.routes\.draw do(\s*\|map\|)?\s*$/
in_root do
inject_into_file 'config/routes.rb', "\n #{routing_code}\n", { :after => sentinel, :verbose => false }
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index bd2260fc29..67a9a6030d 100644
--- a/railties/lib/rails/generators/base.rb
+++ b/railties/lib/rails/generators/base.rb
@@ -3,7 +3,7 @@ begin
rescue LoadError
puts "Thor is not available.\nIf you ran this command from a git checkout " \
"of Rails, please make sure thor is installed,\nand run this command " \
- "as `ruby /path/to/rails myapp --dev`"
+ "as `ruby /path/to/rails new myapp --dev`"
exit
end
diff --git a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
index 2db7f7bbf3..b2c8d7051b 100644
--- a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
@@ -8,17 +8,12 @@ module Erb
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
- class_option :singleton, :type => :boolean, :desc => "Supply to skip index view"
-
def create_root_folder
empty_directory File.join("app/views", controller_file_path)
end
def copy_view_files
- views = available_views
- views.delete("index") if options[:singleton]
-
- views.each do |view|
+ available_views.each do |view|
filename = filename_with_extensions(view)
template filename, File.join("app/views", controller_file_path, filename)
end
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
index 9b83207b3f..d12b2ff0e5 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
@@ -1,10 +1,10 @@
-<%%= form_for(@<%= singular_name %>) do |f| %>
- <%% if @<%= singular_name %>.errors.any? %>
+<%%= form_for(@<%= singular_table_name %>) do |f| %>
+ <%% if @<%= singular_table_name %>.errors.any? %>
<div id="error_explanation">
- <h2><%%= pluralize(@<%= singular_name %>.errors.count, "error") %> prohibited this <%= singular_name %> from being saved:</h2>
+ <h2><%%= pluralize(@<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
<ul>
- <%% @<%= singular_name %>.errors.full_messages.each do |msg| %>
+ <%% @<%= singular_table_name %>.errors.full_messages.each do |msg| %>
<li><%%= msg %></li>
<%% end %>
</ul>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
index 5bc507ffc8..e58b9fbd08 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
@@ -1,6 +1,6 @@
-<h1>Editing <%= singular_name %></h1>
+<h1>Editing <%= singular_table_name %></h1>
<%%= render 'form' %>
-<%%= link_to 'Show', @<%= singular_name %> %> |
-<%%= link_to 'Back', <%= plural_name %>_path %>
+<%%= link_to 'Show', @<%= singular_table_name %> %> |
+<%%= link_to 'Back', <%= index_helper %>_path %>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
index d30d306d42..4c46db4d67 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
@@ -1,4 +1,4 @@
-<h1>Listing <%= plural_name %></h1>
+<h1>Listing <%= plural_table_name %></h1>
<table>
<tr>
@@ -10,18 +10,18 @@
<th></th>
</tr>
-<%% @<%= plural_name %>.each do |<%= singular_name %>| %>
+<%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
<tr>
<% for attribute in attributes -%>
- <td><%%= <%= singular_name %>.<%= attribute.name %> %></td>
+ <td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>
<% end -%>
- <td><%%= link_to 'Show', <%= singular_name %> %></td>
- <td><%%= link_to 'Edit', edit_<%= singular_name %>_path(<%= singular_name %>) %></td>
- <td><%%= link_to 'Destroy', <%= singular_name %>, :confirm => 'Are you sure?', :method => :delete %></td>
+ <td><%%= link_to 'Show', <%= singular_table_name %> %></td>
+ <td><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %></td>
+ <td><%%= link_to 'Destroy', <%= singular_table_name %>, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<%% end %>
</table>
<br />
-<%%= link_to 'New <%= human_name %>', new_<%= singular_name %>_path %>
+<%%= link_to 'New <%= human_name %>', new_<%= singular_table_name %>_path %>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
index 9a1c489331..02ae4d015e 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
@@ -1,5 +1,5 @@
-<h1>New <%= singular_name %></h1>
+<h1>New <%= singular_table_name %></h1>
<%%= render 'form' %>
-<%%= link_to 'Back', <%= plural_name %>_path %>
+<%%= link_to 'Back', <%= index_helper %>_path %>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
index 6b3518717a..c0e5ccff1e 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
@@ -3,10 +3,10 @@
<% for attribute in attributes -%>
<p>
<b><%= attribute.human_name %>:</b>
- <%%= @<%= singular_name %>.<%= attribute.name %> %>
+ <%%= @<%= singular_table_name %>.<%= attribute.name %> %>
</p>
<% end -%>
-<%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
-<%%= link_to 'Back', <%= plural_name %>_path %>
+<%%= link_to 'Edit', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>) %> |
+<%%= link_to 'Back', <%= index_helper %>_path %>
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 8d1dfbd947..44f831e6f3 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -46,6 +46,30 @@ module Rails
end
end
+ def uncountable?
+ singular_name == plural_name
+ end
+
+ def index_helper
+ uncountable? ? "#{plural_table_name}_index" : plural_table_name
+ end
+
+ def singular_table_name
+ @singular_table_name ||= table_name.singularize
+ end
+
+ def plural_table_name
+ @plural_table_name ||= table_name.pluralize
+ end
+
+ def plural_file_name
+ @plural_file_name ||= file_name.pluralize
+ end
+
+ def route_url
+ @route_url ||= class_path.collect{|dname| "/" + dname }.join('') + "/" + plural_file_name
+ end
+
# Tries to retrieve the application name or simple return application.
def application_name
if defined?(Rails) && Rails.application
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index 0b922a89c0..a108968b97 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -32,8 +32,9 @@ gem '<%= gem_for_database %>'<% if require_for_database %>, :require => '<%= req
# gem 'sqlite3-ruby', :require => 'sqlite3'
# gem 'aws-s3', :require => 'aws/s3'
-# Bundle gems for certain environments:
-# gem 'rspec', :group => :test
-# group :test do
+# Bundle gems for the local environment. Make sure to
+# put test-only gems in this group so their generators
+# and rake tasks are available in development mode:
+# group :development, :test do
# gem 'webrat'
# end
diff --git a/railties/lib/rails/generators/rails/app/templates/README b/railties/lib/rails/generators/rails/app/templates/README
index 9ec6db6d71..e2764dee03 100644
--- a/railties/lib/rails/generators/rails/app/templates/README
+++ b/railties/lib/rails/generators/rails/app/templates/README
@@ -37,7 +37,7 @@ link:files/vendor/rails/actionpack/README.html.
3. Go to http://localhost:3000/ and you'll see:
"Welcome aboard: You're riding the Rails!"
-4. Follow the guidelines to start developing your application. You can find
+4. Follow the guidelines to start developing your application. You can find
the following resources handy:
* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
@@ -71,13 +71,13 @@ The result will be a message in your log file along the lines of:
More information on how to use the logger is at http://www.ruby-doc.org/core/
-Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
+Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
several books available online as well:
* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
-These two books will bring you up to speed on the Ruby language and also on
+These two books will bring you up to speed on the Ruby language and also on
programming in general.
@@ -199,7 +199,7 @@ app/controllers
ApplicationController which itself descends from ActionController::Base.
app/models
- Holds models that should be named like post.rb. Models descend from
+ Holds models that should be named like post.rb. Models descend from
ActiveRecord::Base by default.
app/views
diff --git a/railties/lib/rails/generators/rails/app/templates/Rakefile b/railties/lib/rails/generators/rails/app/templates/Rakefile
index 13f1f9fa41..13f1f9fa41 100755..100644
--- a/railties/lib/rails/generators/rails/app/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/app/templates/Rakefile
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index 0066e2b0c2..031466cb86 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -22,7 +22,7 @@ module <%= app_const_base %>
# -- all .rb files in that directory are automatically loaded.
# Add additional load paths for your own custom dirs
- # config.load_paths += %W( #{config.root}/extras )
+ # config.autoload_paths += %W( #{config.root}/extras )
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
index 2784a949fb..df5ef33064 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
@@ -32,40 +32,52 @@
# please refer to the latest documents at http://rubyforge.org/docman/?group_id=2361
development:
- adapter: ibm_db
- username: db2inst1
+ adapter: ibm_db
+ username: db2inst1
password:
- database: <%= app_name[0,4] %>_dev
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
+ database: <%= app_name[0,4] %>_dev
+ #schema: db2inst1
+ #host: localhost
+ #port: 50000
+ #account: my_account
+ #app_user: my_app_user
#application: my_application
#workstation: my_workstation
+ #security: SSL
+ #timeout: 10
+ #authentication: SERVER
+ #parameterized: false
test:
- adapter: ibm_db
- username: db2inst1
+ adapter: ibm_db
+ username: db2inst1
password:
- database: <%= app_name[0,4] %>_tst
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
+ database: <%= app_name[0,4] %>_tst
+ #schema: db2inst1
+ #host: localhost
+ #port: 50000
+ #account: my_account
+ #app_user: my_app_user
#application: my_application
#workstation: my_workstation
+ #security: SSL
+ #timeout: 10
+ #authentication: SERVER
+ #parameterized: false
production:
- adapter: ibm_db
- username: db2inst1
+ adapter: ibm_db
+ username: db2inst1
password:
- database: <%= app_name[0,8] %>
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
+ database: <%= app_name[0,8] %>
+ #schema: db2inst1
+ #host: localhost
+ #port: 50000
+ #account: my_account
+ #app_user: my_app_user
#application: my_application
#workstation: my_workstation
+ #security: SSL
+ #timeout: 10
+ #authentication: SERVER
+ #parameterized: false \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
index 6bf2f7b1fd..ffc8a0a8cb 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
@@ -52,7 +52,7 @@ production:
database: <%= app_name %>_production
pool: 5
username: root
- password:
+ password:
<% if mysql_socket -%>
socket: <%= mysql_socket %>
<% else -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
index a1883f6256..f99ee937f3 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
@@ -36,4 +36,4 @@ production:
adapter: oracle
database: <%= app_name %>_production
username: <%= app_name %>
- password:
+ password:
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
index f0e917dd96..99758dfcf7 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
@@ -16,4 +16,7 @@
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
+
+ # Print deprecation notices to the Rails logger
+ config.active_support.deprecation = :log
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index b9fb13b640..500fc4d860 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -43,4 +43,7 @@
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
+
+ # Send deprecation notices to registered listeners
+ config.active_support.deprecation = :notify
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
index beb28e2229..26cdef071a 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
@@ -29,4 +29,7 @@
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
+
+ # Print deprecation notices to the stderr
+ config.active_support.deprecation = :stderr
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb
index d531b8bb82..9e8b0131f8 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb
@@ -1,6 +1,6 @@
# Be sure to restart your server when you modify this file.
-# Add new inflection rules using the following format
+# Add new inflection rules using the following format
# (all these examples are active by default):
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt
index c2fa31aadb..22aa576f5d 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt
@@ -2,6 +2,6 @@
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
-# Make sure the secret is at least 30 characters and all random,
+# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
Rails.application.config.secret_token = '<%= app_secret %>'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
index d6c0365c04..d42cf3bfdf 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
@@ -1,4 +1,4 @@
-<%= app_const %>.routes.draw do |map|
+<%= app_const %>.routes.draw do
# The priority is based upon order of creation:
# first created -> highest priority.
diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js
index c5fa02ae35..4283ed8982 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js
@@ -1,87 +1,148 @@
-document.observe("dom:loaded", function() {
+(function() {
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ function isEventSupported(eventName) {
+ var el = document.createElement('div');
+ eventName = 'on' + eventName;
+ var isSupported = (eventName in el);
+ if (!isSupported) {
+ el.setAttribute(eventName, 'return;');
+ isSupported = typeof el[eventName] == 'function';
+ }
+ el = null;
+ return isSupported;
+ }
+
+ function isForm(element) {
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
+ }
+
+ function isInput(element) {
+ if (Object.isElement(element)) {
+ var name = element.nodeName.toUpperCase()
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
+ }
+ else return false
+ }
+
+ var submitBubbles = isEventSupported('submit'),
+ changeBubbles = isEventSupported('change')
+
+ if (!submitBubbles || !changeBubbles) {
+ // augment the Event.Handler class to observe custom events when needed
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
+ function(init, element, eventName, selector, callback) {
+ init(element, eventName, selector, callback)
+ // is the handler being attached to an element that doesn't support this event?
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
+ // "submit" => "emulated:submit"
+ this.eventName = 'emulated:' + this.eventName
+ }
+ }
+ )
+ }
+
+ if (!submitBubbles) {
+ // discover forms on the page by observing focus events which always bubble
+ document.on('focusin', 'form', function(focusEvent, form) {
+ // special handler for the real "submit" event (one-time operation)
+ if (!form.retrieve('emulated:submit')) {
+ form.on('submit', function(submitEvent) {
+ var emulated = form.fire('emulated:submit', submitEvent, true)
+ // if custom event received preventDefault, cancel the real one too
+ if (emulated.returnValue === false) submitEvent.preventDefault()
+ })
+ form.store('emulated:submit', true)
+ }
+ })
+ }
+
+ if (!changeBubbles) {
+ // discover form inputs on the page
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
+ // special handler for real "change" events
+ if (!input.retrieve('emulated:change')) {
+ input.on('change', function(changeEvent) {
+ input.fire('emulated:change', changeEvent, true)
+ })
+ input.store('emulated:change', true)
+ }
+ })
+ }
+
function handleRemote(element) {
var method, url, params;
+ var event = element.fire("ajax:before");
+ if (event.stopped) return false;
+
if (element.tagName.toLowerCase() === 'form') {
method = element.readAttribute('method') || 'post';
url = element.readAttribute('action');
- params = element.serialize(true);
+ params = element.serialize();
} else {
method = element.readAttribute('data-method') || 'get';
url = element.readAttribute('href');
params = {};
}
- var event = element.fire("ajax:before");
- if (event.stopped) return false;
-
new Ajax.Request(url, {
method: method,
parameters: params,
- asynchronous: true,
evalScripts: true,
- onLoading: function(request) { element.fire("ajax:loading", {request: request}); },
- onLoaded: function(request) { element.fire("ajax:loaded", {request: request}); },
- onInteractive: function(request) { element.fire("ajax:interactive", {request: request}); },
- onComplete: function(request) { element.fire("ajax:complete", {request: request}); },
- onSuccess: function(request) { element.fire("ajax:success", {request: request}); },
- onFailure: function(request) { element.fire("ajax:failure", {request: request}); }
+ onComplete: function(request) { element.fire("ajax:complete", request); },
+ onSuccess: function(request) { element.fire("ajax:success", request); },
+ onFailure: function(request) { element.fire("ajax:failure", request); }
});
element.fire("ajax:after");
}
function handleMethod(element) {
- var method, url, token_name, token;
-
- method = element.readAttribute('data-method');
- url = element.readAttribute('href');
- csrf_param = $$('meta[name=csrf-param]').first();
- csrf_token = $$('meta[name=csrf-token]').first();
+ var method = element.readAttribute('data-method'),
+ url = element.readAttribute('href'),
+ csrf_param = $$('meta[name=csrf-param]')[0],
+ csrf_token = $$('meta[name=csrf-token]')[0];
var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
- element.parentNode.appendChild(form);
+ element.parentNode.insert(form);
- if (method != 'post') {
+ if (method !== 'post') {
var field = new Element('input', { type: 'hidden', name: '_method', value: method });
- form.appendChild(field);
+ form.insert(field);
}
if (csrf_param) {
- var param = csrf_param.readAttribute('content');
- var token = csrf_token.readAttribute('content');
- var field = new Element('input', { type: 'hidden', name: param, value: token });
- form.appendChild(field);
+ var param = csrf_param.readAttribute('content'),
+ token = csrf_token.readAttribute('content'),
+ field = new Element('input', { type: 'hidden', name: param, value: token });
+ form.insert(field);
}
form.submit();
}
- $(document.body).observe("click", function(event) {
- var message = event.findElement().readAttribute('data-confirm');
- if (message && !confirm(message)) {
- event.stop();
- return false;
- }
- var element = event.findElement("a[data-remote]");
- if (element) {
- handleRemote(element);
- event.stop();
- return true;
- }
+ document.on("click", "*[data-confirm]", function(event, element) {
+ var message = element.readAttribute('data-confirm');
+ if (!confirm(message)) event.stop();
+ });
- var element = event.findElement("a[data-method]");
- if (element) {
- handleMethod(element);
- event.stop();
- return true;
- }
+ document.on("click", "a[data-remote]", function(event, element) {
+ if (event.stopped) return;
+ handleRemote(element);
+ event.stop();
+ });
+
+ document.on("click", "a[data-method]", function(event, element) {
+ if (event.stopped) return;
+ handleMethod(element);
+ event.stop();
});
- // TODO: I don't think submit bubbles in IE
- $(document.body).observe("submit", function(event) {
+ document.on("submit", function(event) {
var element = event.findElement(),
message = element.readAttribute('data-confirm');
if (message && !confirm(message)) {
@@ -103,16 +164,12 @@ document.observe("dom:loaded", function() {
}
});
- $(document.body).observe("ajax:after", function(event) {
- var element = event.findElement();
-
- if (element.tagName.toLowerCase() === 'form') {
- var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
- inputs.each(function(input) {
- input.value = input.readAttribute('data-original-value');
- input.writeAttribute('data-original-value', null);
- input.disabled = false;
- });
- }
+ document.on("ajax:after", "form", function(event, element) {
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
+ inputs.each(function(input) {
+ input.value = input.readAttribute('data-original-value');
+ input.removeAttribute('data-original-value');
+ input.disabled = false;
+ });
});
-}); \ No newline at end of file
+})();
diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE
index db98a2dd1b..67f76aad01 100644
--- a/railties/lib/rails/generators/rails/model/USAGE
+++ b/railties/lib/rails/generators/rails/model/USAGE
@@ -40,6 +40,6 @@ Examples:
Module: app/models/admin.rb
Model: app/models/admin/account.rb
Test: test/unit/admin/account_test.rb
- Fixtures: test/fixtures/admin_accounts.yml
+ Fixtures: test/fixtures/admin/accounts.yml
Migration: db/migrate/XXX_add_admin_accounts.rb
diff --git a/railties/lib/rails/generators/rails/resource/resource_generator.rb b/railties/lib/rails/generators/rails/resource/resource_generator.rb
index 8a46708009..fc070026d6 100644
--- a/railties/lib/rails/generators/rails/resource/resource_generator.rb
+++ b/railties/lib/rails/generators/rails/resource/resource_generator.rb
@@ -14,23 +14,13 @@ module Rails
class_option :actions, :type => :array, :banner => "ACTION ACTION", :default => [],
:desc => "Actions for the resource controller"
- class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
-
def add_resource_route
return if options[:actions].present?
- route "resource#{:s unless options[:singleton]} :#{pluralize?(file_name)}"
+ route_config = class_path.collect{|namespace| "namespace :#{namespace} do " }.join(" ")
+ route_config << "resources :#{file_name.pluralize}"
+ route_config << " end" * class_path.size
+ route route_config
end
-
- protected
-
- def pluralize?(name)
- if options[:singleton]
- name
- else
- name.pluralize
- end
- end
-
end
end
end
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
index 49af2974cd..2271c6f9c1 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
@@ -10,8 +10,6 @@ module Rails
class_option :orm, :banner => "NAME", :type => :string, :required => true,
:desc => "ORM to generate the controller for"
- class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
-
def create_controller_files
template 'controller.rb', File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb")
end
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
index bbdce669dc..b21340f755 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
@@ -1,53 +1,51 @@
class <%= controller_class_name %>Controller < ApplicationController
-<% unless options[:singleton] -%>
- # GET /<%= table_name %>
- # GET /<%= table_name %>.xml
+ # GET <%= route_url %>
+ # GET <%= route_url %>.xml
def index
- @<%= table_name %> = <%= orm_class.all(class_name) %>
+ @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
respond_to do |format|
format.html # index.html.erb
- format.xml { render :xml => @<%= table_name %> }
+ format.xml { render :xml => @<%= plural_table_name %> }
end
end
-<% end -%>
- # GET /<%= table_name %>/1
- # GET /<%= table_name %>/1.xml
+ # GET <%= route_url %>/1
+ # GET <%= route_url %>/1.xml
def show
- @<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
respond_to do |format|
format.html # show.html.erb
- format.xml { render :xml => @<%= file_name %> }
+ format.xml { render :xml => @<%= singular_table_name %> }
end
end
- # GET /<%= table_name %>/new
- # GET /<%= table_name %>/new.xml
+ # GET <%= route_url %>/new
+ # GET <%= route_url %>/new.xml
def new
- @<%= file_name %> = <%= orm_class.build(class_name) %>
+ @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
respond_to do |format|
format.html # new.html.erb
- format.xml { render :xml => @<%= file_name %> }
+ format.xml { render :xml => @<%= singular_table_name %> }
end
end
- # GET /<%= table_name %>/1/edit
+ # GET <%= route_url %>/1/edit
def edit
- @<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
end
- # POST /<%= table_name %>
- # POST /<%= table_name %>.xml
+ # POST <%= route_url %>
+ # POST <%= route_url %>.xml
def create
- @<%= file_name %> = <%= orm_class.build(class_name, "params[:#{file_name}]") %>
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "params[:#{singular_table_name}]") %>
respond_to do |format|
if @<%= orm_instance.save %>
- format.html { redirect_to(@<%= file_name %>, :notice => '<%= human_name %> was successfully created.') }
- format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> }
+ format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully created.') }
+ format.xml { render :xml => @<%= singular_table_name %>, :status => :created, :location => @<%= singular_table_name %> }
else
format.html { render :action => "new" }
format.xml { render :xml => @<%= orm_instance.errors %>, :status => :unprocessable_entity }
@@ -55,14 +53,14 @@ class <%= controller_class_name %>Controller < ApplicationController
end
end
- # PUT /<%= table_name %>/1
- # PUT /<%= table_name %>/1.xml
+ # PUT <%= route_url %>/1
+ # PUT <%= route_url %>/1.xml
def update
- @<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
respond_to do |format|
- if @<%= orm_instance.update_attributes("params[:#{file_name}]") %>
- format.html { redirect_to(@<%= file_name %>, :notice => '<%= human_name %> was successfully updated.') }
+ if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %>
+ format.html { redirect_to(@<%= singular_table_name %>, :notice => '<%= human_name %> was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
@@ -71,14 +69,14 @@ class <%= controller_class_name %>Controller < ApplicationController
end
end
- # DELETE /<%= table_name %>/1
- # DELETE /<%= table_name %>/1.xml
+ # DELETE <%= route_url %>/1
+ # DELETE <%= route_url %>/1.xml
def destroy
- @<%= file_name %> = <%= orm_class.find(class_name, "params[:id]") %>
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
@<%= orm_instance.destroy %>
respond_to do |format|
- format.html { redirect_to(<%= table_name %>_url) }
+ format.html { redirect_to(<%= index_helper %>_url) }
format.xml { head :ok }
end
end
diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb
index 3a98a8f9c1..829f4b200a 100644
--- a/railties/lib/rails/generators/resource_helpers.rb
+++ b/railties/lib/rails/generators/resource_helpers.rb
@@ -72,7 +72,7 @@ module Rails
end
# Initialize ORM::Generators::ActiveModel to access instance methods.
- def orm_instance(name=file_name)
+ def orm_instance(name=singular_table_name)
@orm_instance ||= @orm_class.new(name)
end
end
diff --git a/railties/lib/rails/generators/test_unit/model/model_generator.rb b/railties/lib/rails/generators/test_unit/model/model_generator.rb
index 609b815683..c1dd535dd3 100644
--- a/railties/lib/rails/generators/test_unit/model/model_generator.rb
+++ b/railties/lib/rails/generators/test_unit/model/model_generator.rb
@@ -16,7 +16,7 @@ module TestUnit
def create_fixture_file
if options[:fixture] && options[:fixture_replacement].nil?
- template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml")
+ template 'fixtures.yml', File.join('test/fixtures', class_path, "#{plural_file_name}.yml")
end
end
end
diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
index c0315c7fe6..f7e907a017 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
@@ -6,7 +6,6 @@ module TestUnit
class ScaffoldGenerator < Base
include Rails::Generators::ResourceHelpers
- class_option :singleton, :type => :boolean, :desc => "Supply to create a singleton controller"
check_class_collision :suffix => "ControllerTest"
def create_test_files
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
index 4f8ddbffcf..f23e495450 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -2,50 +2,48 @@ require 'test_helper'
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
setup do
- @<%= file_name %> = <%= table_name %>(:one)
+ @<%= singular_table_name %> = <%= table_name %>(:one)
end
-<% unless options[:singleton] -%>
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:<%= table_name %>)
end
-<% end -%>
test "should get new" do
get :new
assert_response :success
end
- test "should create <%= file_name %>" do
+ test "should create <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count') do
- post :create, :<%= file_name %> => @<%= file_name %>.attributes
+ post :create, :<%= singular_table_name %> => @<%= singular_table_name %>.attributes
end
- assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
+ assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
end
- test "should show <%= file_name %>" do
- get :show, :id => @<%= file_name %>.to_param
+ test "should show <%= singular_table_name %>" do
+ get :show, :id => @<%= singular_table_name %>.to_param
assert_response :success
end
test "should get edit" do
- get :edit, :id => @<%= file_name %>.to_param
+ get :edit, :id => @<%= singular_table_name %>.to_param
assert_response :success
end
- test "should update <%= file_name %>" do
- put :update, :id => @<%= file_name %>.to_param, :<%= file_name %> => @<%= file_name %>.attributes
- assert_redirected_to <%= file_name %>_path(assigns(:<%= file_name %>))
+ test "should update <%= singular_table_name %>" do
+ put :update, :id => @<%= singular_table_name %>.to_param, :<%= singular_table_name %> => @<%= singular_table_name %>.attributes
+ assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
end
- test "should destroy <%= file_name %>" do
+ test "should destroy <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count', -1) do
- delete :destroy, :id => @<%= file_name %>.to_param
+ delete :destroy, :id => @<%= singular_table_name %>.to_param
end
- assert_redirected_to <%= table_name %>_path
+ assert_redirected_to <%= index_helper %>_path
end
end
diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb
index 9a82e051e7..686a2dc0cb 100644
--- a/railties/lib/rails/initializable.rb
+++ b/railties/lib/rails/initializable.rb
@@ -39,11 +39,6 @@ module Rails
select { |i| i.before == initializer.name || i.name == initializer.after }.each(&block)
end
- def initialize(initializers = [])
- super(initializers)
- replace(tsort)
- end
-
def +(other)
Collection.new(to_a + other.to_a)
end
@@ -51,7 +46,7 @@ module Rails
def run_initializers(*args)
return if instance_variable_defined?(:@ran)
- initializers.each do |initializer|
+ initializers.tsort.each do |initializer|
initializer.run(*args)
end
@ran = true
@@ -63,7 +58,7 @@ module Rails
module ClassMethods
def initializers
- @initializers ||= []
+ @initializers ||= Collection.new
end
def initializers_chain
@@ -84,14 +79,6 @@ module Rails
opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] }
initializers << Initializer.new(name, nil, opts, &blk)
end
-
- def run_initializers(*args)
- return if @ran
- initializers_chain.each do |initializer|
- instance_exec(*args, &initializer.block)
- end
- @ran = true
- end
end
end
-end \ No newline at end of file
+end
diff --git a/railties/lib/rails/log_subscriber.rb b/railties/lib/rails/log_subscriber.rb
deleted file mode 100644
index a30701d4d5..0000000000
--- a/railties/lib/rails/log_subscriber.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-require 'active_support/core_ext/class/inheritable_attributes'
-require 'active_support/notifications'
-
-module Rails
- # Rails::LogSubscriber is an object set to consume ActiveSupport::Notifications
- # on initialization with solely purpose of logging. The log subscriber dispatches
- # notifications to a regirested object based on its given namespace.
- #
- # An example would be Active Record log subscriber responsible for logging queries:
- #
- # module ActiveRecord
- # class Railtie
- # class LogSubscriber < Rails::LogSubscriber
- # def sql(event)
- # "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
- # end
- # end
- # end
- # end
- #
- # It's finally registed as:
- #
- # Rails::LogSubscriber.add :active_record, ActiveRecord::Railtie::LogSubscriber.new
- #
- # So whenever a "sql.active_record" notification arrive to Rails::LogSubscriber,
- # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
- # the sql method.
- #
- # This is useful because it avoids spanning several log subscribers just for logging
- # purposes(which slows down the main thread). Besides of providing a centralized
- # facility on top of Rails.logger.
- #
- # Log subscriber also has some helpers to deal with logging and automatically flushes
- # all logs when the request finishes (via action_dispatch.callback notification).
- class LogSubscriber
- mattr_accessor :colorize_logging
- self.colorize_logging = true
-
- # Embed in a String to clear all previous ANSI sequences.
- CLEAR = "\e[0m"
- BOLD = "\e[1m"
-
- # Colors
- BLACK = "\e[30m"
- RED = "\e[31m"
- GREEN = "\e[32m"
- YELLOW = "\e[33m"
- BLUE = "\e[34m"
- MAGENTA = "\e[35m"
- CYAN = "\e[36m"
- WHITE = "\e[37m"
-
- def self.add(namespace, log_subscriber, notifier = ActiveSupport::Notifications)
- log_subscribers << log_subscriber
- @flushable_loggers = nil
-
- log_subscriber.public_methods(false).each do |event|
- notifier.subscribe("#{event}.#{namespace}") do |*args|
- next if log_subscriber.logger.nil?
-
- begin
- log_subscriber.send(event, ActiveSupport::Notifications::Event.new(*args))
- rescue Exception => e
- Rails.logger.error "Could not log #{args[0].inspect} event. #{e.class}: #{e.message}"
- end
- end
- end
- end
-
- def self.log_subscribers
- @log_subscribers ||= []
- end
-
- def self.flushable_loggers
- @flushable_loggers ||= begin
- loggers = log_subscribers.map(&:logger)
- loggers.uniq!
- loggers.select { |l| l.respond_to?(:flush) }
- end
- end
-
- # Flush all log_subscribers' logger.
- def self.flush_all!
- flushable_loggers.each(&:flush)
- end
-
- # By default, we use the Rails.logger for logging.
- def logger
- Rails.logger
- end
-
- protected
-
- %w(info debug warn error fatal unknown).each do |level|
- class_eval <<-METHOD, __FILE__, __LINE__ + 1
- def #{level}(*args, &block)
- return unless logger
- logger.#{level}(*args, &block)
- end
- METHOD
- end
-
- # Set color by using a string or one of the defined constants. If a third
- # option is set to true, it also adds bold to the string. This is based
- # on Highline implementation and it automatically appends CLEAR to the end
- # of the returned String.
- #
- def color(text, color, bold=false)
- return text unless colorize_logging
- color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
- bold = bold ? BOLD : ""
- "#{bold}#{color}#{text}#{CLEAR}"
- end
- end
-end
diff --git a/railties/lib/rails/log_subscriber/test_helper.rb b/railties/lib/rails/log_subscriber/test_helper.rb
deleted file mode 100644
index 9b7b0738cd..0000000000
--- a/railties/lib/rails/log_subscriber/test_helper.rb
+++ /dev/null
@@ -1,97 +0,0 @@
-require 'rails/log_subscriber'
-
-module Rails
- class LogSubscriber
- # Provides some helpers to deal with testing log subscribers by setting up
- # notifications. Take for instance Active Record subscriber tests:
- #
- # class SyncLogSubscriberTest < ActiveSupport::TestCase
- # include Rails::LogSubscriber::TestHelper
- # Rails::LogSubscriber.add(:active_record, ActiveRecord::Railties::LogSubscriber.new)
- #
- # def test_basic_query_logging
- # Developer.all
- # wait
- # assert_equal 1, @logger.logged(:debug).size
- # assert_match /Developer Load/, @logger.logged(:debug).last
- # assert_match /SELECT \* FROM "developers"/, @logger.logged(:debug).last
- # end
- #
- # class SyncLogSubscriberTest < ActiveSupport::TestCase
- # include Rails::LogSubscriber::SyncTestHelper
- # include LogSubscriberTest
- # end
- #
- # class AsyncLogSubscriberTest < ActiveSupport::TestCase
- # include Rails::LogSubscriber::AsyncTestHelper
- # include LogSubscriberTest
- # end
- # end
- #
- # All you need to do is to ensure that your log subscriber is added to Rails::Subscriber,
- # as in the second line of the code above. The test helpers is reponsible for setting
- # up the queue, subscriptions and turning colors in logs off.
- #
- # The messages are available in the @logger instance, which is a logger with limited
- # powers (it actually do not send anything to your output), and you can collect them
- # doing @logger.logged(level), where level is the level used in logging, like info,
- # debug, warn and so on.
- #
- module TestHelper
- def setup
- @logger = MockLogger.new
- @notifier = ActiveSupport::Notifications::Notifier.new(queue)
-
- Rails::LogSubscriber.colorize_logging = false
-
- set_logger(@logger)
- ActiveSupport::Notifications.notifier = @notifier
- end
-
- def teardown
- set_logger(nil)
- ActiveSupport::Notifications.notifier = nil
- end
-
- class MockLogger
- attr_reader :flush_count
-
- def initialize
- @flush_count = 0
- @logged = Hash.new { |h,k| h[k] = [] }
- end
-
- def method_missing(level, message)
- @logged[level] << message
- end
-
- def logged(level)
- @logged[level].compact.map { |l| l.to_s.strip }
- end
-
- def flush
- @flush_count += 1
- end
- end
-
- # Wait notifications to be published.
- def wait
- @notifier.wait
- end
-
- # Overwrite if you use another logger in your log subscriber:
- #
- # def logger
- # ActiveRecord::Base.logger = @logger
- # end
- #
- def set_logger(logger)
- Rails.logger = logger
- end
-
- def queue
- ActiveSupport::Notifications::Fanout.new
- end
- end
- end
-end \ No newline at end of file
diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb
index 1c9e308631..7a65188a9a 100644
--- a/railties/lib/rails/paths.rb
+++ b/railties/lib/rails/paths.rb
@@ -25,9 +25,7 @@ module Rails
def initialize(path)
raise if path.is_a?(Array)
-
@children = {}
-
@path = path
@root = self
@all_paths = []
@@ -38,14 +36,18 @@ module Rails
@all_paths
end
- def load_once
- filter_by(:load_once?)
+ def autoload_once
+ filter_by(:autoload_once?)
end
def eager_load
filter_by(:eager_load?)
end
+ def autoload_paths
+ filter_by(:autoload?)
+ end
+
def load_paths
filter_by(:load_path?)
end
@@ -61,15 +63,17 @@ module Rails
protected
def filter_by(constraint)
- all_paths.map do |path|
+ all = []
+ all_paths.each do |path|
if path.send(constraint)
paths = path.paths
paths -= path.children.values.map { |p| p.send(constraint) ? [] : p.paths }.flatten
- paths
- else
- []
+ all.concat(paths)
end
- end.flatten.uniq.select { |p| File.exists?(p) }
+ end
+ all.uniq!
+ all.reject! { |p| !File.exists?(p) }
+ all
end
end
@@ -80,15 +84,16 @@ module Rails
attr_accessor :glob
def initialize(root, *paths)
- @options = paths.last.is_a?(::Hash) ? paths.pop : {}
+ options = paths.last.is_a?(::Hash) ? paths.pop : {}
@children = {}
@root = root
@paths = paths.flatten
- @glob = @options.delete(:glob)
+ @glob = options[:glob]
- @load_once = @options[:load_once]
- @eager_load = @options[:eager_load]
- @load_path = @options[:load_path] || @eager_load || @load_once
+ autoload_once! if options[:autoload_once]
+ eager_load! if options[:eager_load]
+ autoload! if options[:autoload]
+ load_path! if options[:load_path]
@root.all_paths << self
end
@@ -111,24 +116,30 @@ module Rails
@paths.concat paths
end
- def load_once!
- @load_once = true
- @load_path = true
+ def autoload_once!
+ @autoload_once = true
end
- def load_once?
- @load_once
+ def autoload_once?
+ @autoload_once
end
def eager_load!
@eager_load = true
- @load_path = true
end
def eager_load?
@eager_load
end
+ def autoload!
+ @autoload = true
+ end
+
+ def autoload?
+ @autoload
+ end
+
def load_path!
@load_path = true
end
diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb
index fcdd099135..be229cc9a2 100644
--- a/railties/lib/rails/plugin.rb
+++ b/railties/lib/rails/plugin.rb
@@ -61,6 +61,16 @@ module Rails
@config ||= Engine::Configuration.new
end
+ initializer :handle_lib_autoload, :before => :set_load_path do |app|
+ paths = if app.config.reload_plugins
+ config.autoload_paths
+ else
+ config.autoload_once_paths
+ end
+
+ paths.concat config.paths.lib.to_a
+ end
+
initializer :load_init_rb, :before => :load_config_initializers do |app|
files = %w(rails/init.rb init.rb).map { |path| File.expand_path path, root }
if initrb = files.find { |path| File.file? path }
@@ -77,11 +87,5 @@ module Rails
raise "\"#{name}\" is a Railtie/Engine and cannot be installed as plugin"
end
end
-
- protected
-
- def reloadable?(app)
- app.config.reload_plugins
- end
end
end
diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb
index 73e9af3b41..b3dc1f894c 100644
--- a/railties/lib/rails/rack/logger.rb
+++ b/railties/lib/rails/rack/logger.rb
@@ -1,10 +1,9 @@
-require 'rails/log_subscriber'
require 'active_support/core_ext/time/conversions'
module Rails
module Rack
# Log the request started and flush all loggers after it.
- class Logger < Rails::LogSubscriber
+ class Logger < ActiveSupport::LogSubscriber
def initialize(app)
@app = app
end
@@ -16,20 +15,19 @@ module Rails
after_dispatch(env)
end
- protected
+ protected
- def before_dispatch(env)
- request = ActionDispatch::Request.new(env)
- path = request.fullpath
+ def before_dispatch(env)
+ request = ActionDispatch::Request.new(env)
+ path = request.fullpath
- info "\n\nStarted #{env["REQUEST_METHOD"]} \"#{path}\" " \
- "for #{request.ip} at #{Time.now.to_default_s}"
- end
-
- def after_dispatch(env)
- Rails::LogSubscriber.flush_all!
- end
+ info "\n\nStarted #{env["REQUEST_METHOD"]} \"#{path}\" " \
+ "for #{request.ip} at #{Time.now.to_default_s}"
+ end
+ def after_dispatch(env)
+ ActiveSupport::LogSubscriber.flush_all!
+ end
end
end
end
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index ad776933f2..dbdbfea509 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -114,36 +114,6 @@ module Rails
# end
# end
#
- # == Adding your subscriber
- #
- # Since version 3.0, Rails ships with a notification system which is used for several
- # purposes, including logging. If you are sending notifications in your Railtie, you may
- # want to add a subscriber to consume such notifications for logging purposes.
- #
- # The subscriber is added under the railtie_name namespace and only consumes notifications
- # under the given namespace. For example, let's suppose your railtie is publishing the
- # following "something_expensive" instrumentation:
- #
- # ActiveSupport::Notifications.instrument "my_railtie.something_expensive" do
- # # something expensive
- # end
- #
- # You can log this instrumentation with your own Rails::Subscriber:
- #
- # class MyRailtie::Subscriber < Rails::Subscriber
- # def something_expensive(event)
- # info("Something expensive took %.1fms" % event.duration)
- # end
- # end
- #
- # By registering it:
- #
- # class MyRailtie < Railtie
- # subscriber :my_gem, MyRailtie::Subscriber.new
- # end
- #
- # Take a look in Rails::Subscriber docs for more information.
- #
# == Application, Plugin and Engine
#
# A Rails::Engine is nothing more than a Railtie with some initializers already set.
@@ -176,8 +146,8 @@ module Rails
ActiveSupport::Deprecation.warn "railtie_name is deprecated and has no effect", caller
end
- def log_subscriber(name, log_subscriber)
- Rails::LogSubscriber.add(name, log_subscriber)
+ def log_subscriber(*)
+ ActiveSupport::Deprecation.warn "log_subscriber is deprecated and has no effect", caller
end
def rake_tasks(&blk)
diff --git a/railties/lib/rails/webrick_server.rb b/railties/lib/rails/webrick_server.rb
deleted file mode 100644
index f3b74c28d3..0000000000
--- a/railties/lib/rails/webrick_server.rb
+++ /dev/null
@@ -1,156 +0,0 @@
-# Donated by Florian Gross
-
-require 'webrick'
-require 'cgi'
-require 'stringio'
-require 'dispatcher'
-
-include WEBrick
-
-class CGI #:nodoc:
- def stdinput
- @stdin || $stdin
- end
-
- def env_table
- @env_table || ENV
- end
-
- def initialize(type = "query", table = nil, stdin = nil)
- @env_table, @stdin = table, stdin
-
- if defined?(MOD_RUBY) && !ENV.key?("GATEWAY_INTERFACE")
- Apache.request.setup_cgi_env
- end
-
- extend QueryExtension
- @multipart = false
- if defined?(CGI_PARAMS)
- warn "do not use CGI_PARAMS and CGI_COOKIES"
- @params = CGI_PARAMS.dup
- @cookies = CGI_COOKIES.dup
- else
- initialize_query() # set @params, @cookies
- end
- @output_cookies = nil
- @output_hidden = nil
- end
-end
-
-# A custom dispatch servlet for use with WEBrick. It dispatches requests
-# (using the Rails Dispatcher) to the appropriate controller/action. By default,
-# it restricts WEBrick to a managing a single Rails request at a time, but you
-# can change this behavior by setting ActionController::Base.allow_concurrency
-# to true.
-class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
- # Start the WEBrick server with the given options, mounting the
- # DispatchServlet at <tt>/</tt>.
- def self.dispatch(options = {})
- Socket.do_not_reverse_lookup = true # patch for OS X
-
- params = { :Port => options[:port].to_i,
- :ServerType => options[:server_type],
- :BindAddress => options[:ip] }
- params[:MimeTypes] = options[:mime_types] if options[:mime_types]
-
- server = WEBrick::HTTPServer.new(params)
- server.mount('/', DispatchServlet, options)
-
- trap("INT") { server.shutdown }
- server.start
- end
-
- def initialize(server, options) #:nodoc:
- @server_options = options
- @file_handler = WEBrick::HTTPServlet::FileHandler.new(server, options[:server_root])
- # Change to the Rails.root, since Webrick::Daemon.start does a Dir::cwd("/")
- # OPTIONS['working_directory'] is an absolute path of the Rails.root, set in railties/lib/commands/servers/webrick.rb
- Dir.chdir(OPTIONS['working_directory']) if defined?(OPTIONS) && File.directory?(OPTIONS['working_directory'])
- super
- end
-
- def service(req, res) #:nodoc:
- unless handle_file(req, res)
- unless handle_dispatch(req, res)
- raise WEBrick::HTTPStatus::NotFound, "`#{req.path}' not found."
- end
- end
- end
-
- def handle_file(req, res) #:nodoc:
- begin
- req = req.dup
- path = req.path.dup
-
- # Add .html if the last path piece has no . in it
- path << '.html' if path != '/' && (%r{(^|/)[^./]+$} =~ path)
- path.gsub!('+', ' ') # Unescape + since FileHandler doesn't do so.
-
- req.instance_variable_set(:@path_info, path) # Set the modified path...
-
- @file_handler.send(:service, req, res)
- return true
- rescue HTTPStatus::PartialContent, HTTPStatus::NotModified => err
- res.set_error(err)
- return true
- rescue => err
- return false
- end
- end
-
- def handle_dispatch(req, res, origin = nil) #:nodoc:
- data = StringIO.new
- Dispatcher.dispatch(
- CGI.new("query", create_env_table(req, origin), StringIO.new(req.body || "")),
- ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS,
- data
- )
-
- header, body = extract_header_and_body(data)
-
- set_charset(header)
- assign_status(res, header)
- res.cookies.concat(header.delete('set-cookie') || [])
- header.each { |key, val| res[key] = val.join(", ") }
-
- res.body = body
- return true
- rescue => err
- p err, err.backtrace
- return false
- end
-
- private
- def create_env_table(req, origin)
- env = req.meta_vars.clone
- env.delete "SCRIPT_NAME"
- env["QUERY_STRING"] = req.request_uri.query
- env["REQUEST_URI"] = origin if origin
- return env
- end
-
- def extract_header_and_body(data)
- data.rewind
- data = data.read
-
- raw_header, body = *data.split(/^[\xd\xa]{2}/on, 2)
- header = WEBrick::HTTPUtils::parse_header(raw_header)
-
- return header, body
- end
-
- def set_charset(header)
- ct = header["content-type"]
- if ct.any? { |x| x =~ /^text\// } && ! ct.any? { |x| x =~ /charset=/ }
- ch = @server_options[:charset] || "UTF-8"
- ct.find { |x| x =~ /^text\// } << ("; charset=" + ch)
- end
- end
-
- def assign_status(res, header)
- if /^(\d+)/ =~ header['status'][0]
- res.status = $1.to_i
- header.delete('status')
- end
- end
-end