diff options
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 41 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/deprecated_body.rb | 38 | ||||
-rw-r--r-- | actionmailer/test/mail_service_test.rb | 10 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/base.rb | 140 | ||||
-rw-r--r-- | actionpack/lib/action_controller/deprecated/dispatcher.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/cookies.rb | 186 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/instrumentation.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/testing.rb | 3 | ||||
-rw-r--r-- | actionpack/lib/action_controller/railtie.rb | 50 | ||||
-rw-r--r-- | actionpack/lib/action_controller/railties/subscriber.rb | 7 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/callbacks.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/cookies.rb | 216 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/notifications.rb | 24 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/show_exceptions.rb | 32 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb | 9 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/railtie.rb | 29 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/railties/subscriber.rb | 17 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 59 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/debug_helper.rb | 4 | ||||
-rw-r--r-- | actionpack/test/abstract_unit.rb | 1 | ||||
-rw-r--r-- | actionpack/test/activerecord/controller_runtime_test.rb | 4 | ||||
-rw-r--r-- | actionpack/test/controller/cookie_test.rb | 37 | ||||
-rw-r--r-- | actionpack/test/controller/filter_params_test.rb | 27 | ||||
-rw-r--r-- | actionpack/test/controller/flash_test.rb | 2 | ||||
-rw-r--r-- | actionpack/test/controller/new_base/base_test.rb | 28 | ||||
-rw-r--r-- | actionpack/test/controller/subscriber_test.rb | 42 | ||||
-rw-r--r-- | actionpack/test/dispatch/callbacks_test.rb | 12 | ||||
-rw-r--r-- | actionpack/test/dispatch/response_test.rb | 9 | ||||
-rw-r--r-- | actionpack/test/dispatch/session/cookie_store_test.rb | 4 | ||||
-rw-r--r-- | actionpack/test/dispatch/show_exceptions_test.rb | 45 | ||||
-rw-r--r-- | actionpack/test/dispatch/subscriber_test.rb | 112 | ||||
-rw-r--r-- | actionpack/test/fixtures/reply.rb | 2 | ||||
-rw-r--r-- | activemodel/lib/active_model/errors.rb | 2 | ||||
-rw-r--r-- | activemodel/lib/active_model/validations/validates.rb | 2 | ||||
-rw-r--r-- | activemodel/test/cases/validations_test.rb | 8 | ||||
-rw-r--r-- | activerecord/CHANGELOG | 10 | ||||
-rwxr-xr-x | activerecord/lib/active_record/associations.rb | 34 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/association_collection.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/has_many_association.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/associations/has_many_through_association.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/autosave_association.rb | 10 | ||||
-rwxr-xr-x | activerecord/lib/active_record/base.rb | 10 | ||||
-rw-r--r-- | activerecord/lib/active_record/calculations.rb | 59 | ||||
-rw-r--r-- | activerecord/lib/active_record/callbacks.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/named_scope.rb | 153 | ||||
-rw-r--r-- | activerecord/lib/active_record/railties/databases.rake | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/railties/subscriber.rb | 2 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation.rb | 44 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/finder_methods.rb | 36 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/predicate_builder.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/spawn_methods.rb | 20 | ||||
-rw-r--r-- | activerecord/lib/active_record/transactions.rb | 4 | ||||
-rw-r--r-- | activerecord/lib/active_record/validations.rb | 12 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record.rb (renamed from railties/lib/rails/generators/active_record.rb) | 8 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record/migration/migration_generator.rb (renamed from railties/lib/rails/generators/active_record/migration/migration_generator.rb) | 2 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record/migration/templates/migration.rb (renamed from railties/lib/rails/generators/active_record/migration/templates/migration.rb) | 0 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record/model/model_generator.rb (renamed from railties/lib/rails/generators/active_record/model/model_generator.rb) | 2 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record/model/templates/migration.rb (renamed from railties/lib/rails/generators/active_record/model/templates/migration.rb) | 0 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record/model/templates/model.rb (renamed from railties/lib/rails/generators/active_record/model/templates/model.rb) | 0 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record/observer/observer_generator.rb (renamed from railties/lib/rails/generators/active_record/observer/observer_generator.rb) | 2 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record/observer/templates/observer.rb (renamed from railties/lib/rails/generators/active_record/observer/templates/observer.rb) | 0 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record/session_migration/session_migration_generator.rb (renamed from railties/lib/rails/generators/active_record/session_migration/session_migration_generator.rb) | 2 | ||||
-rw-r--r-- | activerecord/lib/generators/active_record/session_migration/templates/migration.rb (renamed from railties/lib/rails/generators/active_record/session_migration/templates/migration.rb) | 0 | ||||
-rw-r--r-- | activerecord/test/cases/autosave_association_test.rb | 12 | ||||
-rwxr-xr-x | activerecord/test/cases/base_test.rb | 4 | ||||
-rw-r--r-- | activerecord/test/cases/method_scoping_test.rb | 14 | ||||
-rw-r--r-- | activerecord/test/cases/named_scope_test.rb | 43 | ||||
-rw-r--r-- | activerecord/test/cases/relations_test.rb | 17 | ||||
-rw-r--r-- | activerecord/test/cases/validations_test.rb | 29 | ||||
-rw-r--r-- | activerecord/test/models/comment.rb | 6 | ||||
-rw-r--r-- | activerecord/test/models/company.rb | 8 | ||||
-rw-r--r-- | activerecord/test/models/developer.rb | 4 | ||||
-rw-r--r-- | activerecord/test/models/organization.rb | 2 | ||||
-rw-r--r-- | activerecord/test/models/person.rb | 4 | ||||
-rw-r--r-- | activerecord/test/models/post.rb | 18 | ||||
-rw-r--r-- | activerecord/test/models/reply.rb | 2 | ||||
-rw-r--r-- | activerecord/test/models/topic.rb | 22 | ||||
-rw-r--r-- | activeresource/lib/active_resource/validations.rb | 15 | ||||
-rw-r--r-- | activeresource/test/cases/validations_test.rb | 13 | ||||
-rw-r--r-- | activesupport/lib/active_support/backtrace_cleaner.rb | 32 | ||||
-rw-r--r-- | activesupport/lib/active_support/cache.rb | 8 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/exception.rb | 47 | ||||
-rw-r--r-- | activesupport/lib/active_support/notifications.rb | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/notifications/instrumenter.rb | 9 | ||||
-rw-r--r-- | activesupport/test/core_ext/exception_test.rb | 69 | ||||
-rw-r--r-- | activesupport/test/notifications_test.rb | 16 | ||||
-rwxr-xr-x | railties/bin/rails | 2 | ||||
-rw-r--r-- | railties/lib/generators/erb.rb (renamed from railties/lib/rails/generators/erb.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/erb/controller/controller_generator.rb (renamed from railties/lib/rails/generators/erb/controller/controller_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/erb/controller/templates/view.html.erb (renamed from railties/lib/rails/generators/erb/controller/templates/view.html.erb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/erb/mailer/mailer_generator.rb (renamed from railties/lib/rails/generators/erb/mailer/mailer_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/erb/mailer/templates/view.erb (renamed from railties/lib/rails/generators/erb/mailer/templates/view.erb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/erb/scaffold/scaffold_generator.rb (renamed from railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/erb/scaffold/templates/_form.html.erb (renamed from railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/erb/scaffold/templates/edit.html.erb (renamed from railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/erb/scaffold/templates/index.html.erb (renamed from railties/lib/rails/generators/erb/scaffold/templates/index.html.erb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/erb/scaffold/templates/layout.html.erb (renamed from railties/lib/rails/generators/erb/scaffold/templates/layout.html.erb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/erb/scaffold/templates/new.html.erb (renamed from railties/lib/rails/generators/erb/scaffold/templates/new.html.erb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/erb/scaffold/templates/show.html.erb (renamed from railties/lib/rails/generators/erb/scaffold/templates/show.html.erb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/USAGE (renamed from railties/lib/rails/generators/rails/app/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/app_generator.rb (renamed from railties/lib/rails/generators/rails/app/app_generator.rb) | 6 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/Gemfile (renamed from railties/lib/rails/generators/rails/app/templates/Gemfile) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/README (renamed from railties/lib/rails/generators/rails/app/templates/README) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/Rakefile (renamed from railties/lib/rails/generators/rails/app/templates/Rakefile) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb (renamed from railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb (renamed from railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/app/models/.empty_directory (renamed from railties/lib/rails/generators/rails/app/templates/app/models/.empty_directory) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory (renamed from railties/lib/rails/generators/rails/app/templates/app/views/layouts/.empty_directory) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config.ru (renamed from railties/lib/rails/generators/rails/app/templates/config.ru) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/application.rb (renamed from railties/lib/rails/generators/rails/app/templates/config/application.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/boot.rb (renamed from railties/lib/rails/generators/rails/app/templates/config/boot.rb) | 13 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/databases/frontbase.yml (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/databases/mysql.yml (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/databases/oracle.yml (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/databases/postgresql.yml (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/environment.rb (renamed from railties/lib/rails/generators/rails/app/templates/config/environment.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/environments/development.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/environments/production.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/environments/test.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/initializers/inflections.rb (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/locales/en.yml (renamed from railties/lib/rails/generators/rails/app/templates/config/locales/en.yml) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/config/routes.rb (renamed from railties/lib/rails/generators/rails/app/templates/config/routes.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/db/seeds.rb (renamed from railties/lib/rails/generators/rails/app/templates/db/seeds.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/doc/README_FOR_APP (renamed from railties/lib/rails/generators/rails/app/templates/doc/README_FOR_APP) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/gitignore (renamed from railties/lib/rails/generators/rails/app/templates/gitignore) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/404.html (renamed from railties/lib/rails/generators/rails/app/templates/public/404.html) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/422.html (renamed from railties/lib/rails/generators/rails/app/templates/public/422.html) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/500.html (renamed from railties/lib/rails/generators/rails/app/templates/public/500.html) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/favicon.ico (renamed from railties/lib/rails/generators/rails/app/templates/public/favicon.ico) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/images/rails.png (renamed from railties/lib/rails/generators/rails/app/templates/public/images/rails.png) | bin | 6646 -> 6646 bytes | |||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/index.html (renamed from railties/lib/rails/generators/rails/app/templates/public/index.html) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/javascripts/application.js (renamed from railties/lib/rails/generators/rails/app/templates/public/javascripts/application.js) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/javascripts/controls.js (renamed from railties/lib/rails/generators/rails/app/templates/public/javascripts/controls.js) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js (renamed from railties/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/javascripts/effects.js (renamed from railties/lib/rails/generators/rails/app/templates/public/javascripts/effects.js) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/javascripts/prototype.js (renamed from railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/robots.txt (renamed from railties/lib/rails/generators/rails/app/templates/public/robots.txt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory (renamed from railties/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/about (renamed from railties/lib/rails/generators/rails/app/templates/script/about) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/console.tt (renamed from railties/lib/rails/generators/rails/app/templates/script/console.tt) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/dbconsole.tt (renamed from railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/destroy (renamed from railties/lib/rails/generators/rails/app/templates/script/destroy) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/generate (renamed from railties/lib/rails/generators/rails/app/templates/script/generate) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/performance/benchmarker (renamed from railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/performance/profiler (renamed from railties/lib/rails/generators/rails/app/templates/script/performance/profiler) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/plugin (renamed from railties/lib/rails/generators/rails/app/templates/script/plugin) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/runner (renamed from railties/lib/rails/generators/rails/app/templates/script/runner) | 0 | ||||
-rwxr-xr-x | railties/lib/generators/rails/app/templates/script/server.tt (renamed from railties/lib/rails/generators/rails/app/templates/script/server.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory (renamed from railties/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/test/functional/.empty_directory (renamed from railties/lib/rails/generators/rails/app/templates/test/functional/.empty_directory) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/test/integration/.empty_directory (renamed from railties/lib/rails/generators/rails/app/templates/test/integration/.empty_directory) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/test/performance/browsing_test.rb (renamed from railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/test/test_helper.rb (renamed from railties/lib/rails/generators/rails/app/templates/test/test_helper.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/app/templates/test/unit/.empty_directory (renamed from railties/lib/rails/generators/rails/app/templates/test/unit/.empty_directory) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/controller/USAGE (renamed from railties/lib/rails/generators/rails/controller/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/controller/controller_generator.rb (renamed from railties/lib/rails/generators/rails/controller/controller_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/controller/templates/controller.rb (renamed from railties/lib/rails/generators/rails/controller/templates/controller.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/generator/USAGE (renamed from railties/lib/rails/generators/rails/generator/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/generator/generator_generator.rb (renamed from railties/lib/rails/generators/rails/generator/generator_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/generator/templates/%file_name%_generator.rb.tt (renamed from railties/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/generator/templates/USAGE.tt (renamed from railties/lib/rails/generators/rails/generator/templates/USAGE.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/generator/templates/templates/.empty_directory (renamed from railties/lib/rails/generators/rails/generator/templates/templates/.empty_directory) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/helper/USAGE (renamed from railties/lib/rails/generators/rails/helper/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/helper/helper_generator.rb (renamed from railties/lib/rails/generators/rails/helper/helper_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/helper/templates/helper.rb (renamed from railties/lib/rails/generators/rails/helper/templates/helper.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/integration_test/USAGE (renamed from railties/lib/rails/generators/rails/integration_test/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/integration_test/integration_test_generator.rb (renamed from railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/mailer/USAGE (renamed from railties/lib/rails/generators/rails/mailer/USAGE) | 4 | ||||
-rw-r--r-- | railties/lib/generators/rails/mailer/mailer_generator.rb (renamed from railties/lib/rails/generators/rails/mailer/mailer_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/rails/mailer/templates/mailer.rb (renamed from railties/lib/rails/generators/rails/mailer/templates/mailer.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/metal/USAGE (renamed from railties/lib/rails/generators/rails/metal/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/metal/metal_generator.rb (renamed from railties/lib/rails/generators/rails/metal/metal_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/metal/templates/metal.rb (renamed from railties/lib/rails/generators/rails/metal/templates/metal.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/migration/USAGE (renamed from railties/lib/rails/generators/rails/migration/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/migration/migration_generator.rb (renamed from railties/lib/rails/generators/rails/migration/migration_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/model/USAGE (renamed from railties/lib/rails/generators/rails/model/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/model/model_generator.rb (renamed from railties/lib/rails/generators/rails/model/model_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/model_subclass/model_subclass_generator.rb (renamed from railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb) | 1 | ||||
-rw-r--r-- | railties/lib/generators/rails/observer/USAGE (renamed from railties/lib/rails/generators/rails/observer/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/observer/observer_generator.rb (renamed from railties/lib/rails/generators/rails/observer/observer_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/performance_test/USAGE (renamed from railties/lib/rails/generators/rails/performance_test/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/performance_test/performance_test_generator.rb (renamed from railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/USAGE (renamed from railties/lib/rails/generators/rails/plugin/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/plugin_generator.rb (renamed from railties/lib/rails/generators/rails/plugin/plugin_generator.rb) | 14 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/templates/MIT-LICENSE.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/templates/README.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/README) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/templates/Rakefile.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/Rakefile) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/templates/init.rb (renamed from railties/lib/rails/generators/rails/plugin/templates/init.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/templates/install.rb (renamed from railties/lib/rails/generators/rails/plugin/templates/install.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/lib/%file_name%.rb.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/plugin/templates/uninstall.rb (renamed from railties/lib/rails/generators/rails/plugin/templates/uninstall.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/resource/USAGE (renamed from railties/lib/rails/generators/rails/resource/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/resource/resource_generator.rb (renamed from railties/lib/rails/generators/rails/resource/resource_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/rails/scaffold/USAGE (renamed from railties/lib/rails/generators/rails/scaffold/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/scaffold/scaffold_generator.rb (renamed from railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/rails/scaffold_controller/USAGE (renamed from railties/lib/rails/generators/rails/scaffold_controller/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/scaffold_controller/scaffold_controller_generator.rb (renamed from railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/scaffold_controller/templates/controller.rb (renamed from railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/session_migration/USAGE (renamed from railties/lib/rails/generators/rails/session_migration/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/session_migration/session_migration_generator.rb (renamed from railties/lib/rails/generators/rails/session_migration/session_migration_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/stylesheets/USAGE (renamed from railties/lib/rails/generators/rails/stylesheets/USAGE) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/stylesheets/stylesheets_generator.rb (renamed from railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/rails/stylesheets/templates/scaffold.css (renamed from railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit.rb (renamed from railties/lib/rails/generators/test_unit.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/controller/controller_generator.rb (renamed from railties/lib/rails/generators/test_unit/controller/controller_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/controller/templates/functional_test.rb (renamed from railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/helper/helper_generator.rb (renamed from railties/lib/rails/generators/test_unit/helper/helper_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/helper/templates/helper_test.rb (renamed from railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/integration/integration_generator.rb (renamed from railties/lib/rails/generators/test_unit/integration/integration_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/integration/templates/integration_test.rb (renamed from railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/mailer/mailer_generator.rb (renamed from railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb) | 4 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/mailer/templates/fixture (renamed from railties/lib/rails/generators/test_unit/mailer/templates/fixture) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/mailer/templates/functional_test.rb (renamed from railties/lib/rails/generators/test_unit/mailer/templates/unit_test.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/model/model_generator.rb (renamed from railties/lib/rails/generators/test_unit/model/model_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/model/templates/fixtures.yml (renamed from railties/lib/rails/generators/test_unit/model/templates/fixtures.yml) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/model/templates/unit_test.rb (renamed from railties/lib/rails/generators/test_unit/model/templates/unit_test.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/observer/observer_generator.rb (renamed from railties/lib/rails/generators/test_unit/observer/observer_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/observer/templates/unit_test.rb (renamed from railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/performance/performance_generator.rb (renamed from railties/lib/rails/generators/test_unit/performance/performance_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/performance/templates/performance_test.rb (renamed from railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/plugin/plugin_generator.rb (renamed from railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/plugin/templates/%file_name%_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/plugin/templates/test_helper.rb (renamed from railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb) | 0 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/scaffold/scaffold_generator.rb (renamed from railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb) | 2 | ||||
-rw-r--r-- | railties/lib/generators/test_unit/scaffold/templates/functional_test.rb (renamed from railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb) | 0 | ||||
-rw-r--r-- | railties/lib/rails.rb | 5 | ||||
-rw-r--r-- | railties/lib/rails/application.rb | 14 | ||||
-rw-r--r-- | railties/lib/rails/backtrace_cleaner.rb | 31 | ||||
-rw-r--r-- | railties/lib/rails/bootstrap.rb | 11 | ||||
-rw-r--r-- | railties/lib/rails/configuration.rb | 23 | ||||
-rw-r--r-- | railties/lib/rails/deprecation.rb | 6 | ||||
-rw-r--r-- | railties/lib/rails/generators.rb | 184 | ||||
-rw-r--r-- | railties/lib/rails/generators/base.rb | 8 | ||||
-rw-r--r-- | railties/lib/rails/generators/named_base.rb | 8 | ||||
-rw-r--r-- | railties/lib/rails/generators/resource_helpers.rb | 10 | ||||
-rw-r--r-- | railties/lib/rails/plugin.rb | 8 | ||||
-rw-r--r-- | railties/lib/rails/rack.rb | 5 | ||||
-rw-r--r-- | railties/lib/rails/rack/metal.rb | 26 | ||||
-rw-r--r-- | railties/lib/rails/subscriber.rb | 2 | ||||
-rw-r--r-- | railties/lib/rails/tasks/documentation.rake | 2 | ||||
-rw-r--r-- | railties/lib/rails/tasks/framework.rake | 7 | ||||
-rw-r--r-- | railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb | 9 | ||||
-rw-r--r-- | railties/test/application/middleware_test.rb | 2 | ||||
-rw-r--r-- | railties/test/application/notifications_test.rb | 2 | ||||
-rw-r--r-- | railties/test/backtrace_cleaner_test.rb | 4 | ||||
-rw-r--r-- | railties/test/fixtures/lib/generators/active_record/fixjour_generator.rb (renamed from railties/test/fixtures/lib/generators/active_record/fixjour/fixjour_generator.rb) | 2 | ||||
-rw-r--r-- | railties/test/fixtures/lib/generators/rails/javascripts_generator.rb | 4 | ||||
-rw-r--r-- | railties/test/fixtures/lib/generators/wrong_generator.rb (renamed from railties/test/fixtures/vendor/gems/gems/wrong/lib/generators/wrong_generator.rb) | 0 | ||||
-rw-r--r-- | railties/test/fixtures/vendor/another_gem_path/xspec/lib/generators/xspec_generator.rb | 2 | ||||
-rw-r--r-- | railties/test/fixtures/vendor/plugins/mspec/lib/rails_generators/mspec_generator.rb | 2 | ||||
-rw-r--r-- | railties/test/generators/actions_test.rb | 18 | ||||
-rw-r--r-- | railties/test/generators/app_generator_test.rb | 16 | ||||
-rw-r--r-- | railties/test/generators/controller_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/generator_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/generators_test_helper.rb | 22 | ||||
-rw-r--r-- | railties/test/generators/helper_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/integration_test_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/mailer_generator_test.rb | 13 | ||||
-rw-r--r-- | railties/test/generators/metal_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/migration_generator_test.rb | 6 | ||||
-rw-r--r-- | railties/test/generators/model_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/named_base_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/observer_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/performance_test_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/plugin_generator_test.rb | 20 | ||||
-rw-r--r-- | railties/test/generators/resource_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/scaffold_controller_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/scaffold_generator_test.rb | 5 | ||||
-rw-r--r-- | railties/test/generators/session_migration_generator_test.rb | 6 | ||||
-rw-r--r-- | railties/test/generators/stylesheets_generator_test.rb | 6 | ||||
-rw-r--r-- | railties/test/generators_test.rb | 137 | ||||
-rw-r--r-- | railties/test/subscriber_test.rb | 6 |
284 files changed, 1497 insertions, 1308 deletions
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 5be1beaedb..a8233512ab 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -23,8 +23,7 @@ module ActionMailer #:nodoc: # bcc ["bcc@example.com", "Order Watcher <watcher@example.com>"] # from "system@example.com" # subject "New account information" - # - # @account = recipient + # body :account => recipient # end # end # @@ -144,12 +143,13 @@ module ActionMailer #:nodoc: # subject "New account information" # from "system@example.com" # content_type "multipart/alternative" + # body :account => recipient # # part :content_type => "text/html", - # :body => render_message("signup-as-html", :account => recipient) + # :data => render_message("signup-as-html") # # part "text/plain" do |p| - # p.body = render_message("signup-as-plain", :account => recipient) + # p.body = render_message("signup-as-plain") # p.content_transfer_encoding = "base64" # end # end @@ -454,11 +454,13 @@ module ActionMailer #:nodoc: # body, headers, etc.) can be set on it. def part(params) params = {:content_type => params} if String === params + if custom_headers = params.delete(:headers) ActiveSupport::Deprecation.warn('Passing custom headers with :headers => {} is deprecated. ' << 'Please just pass in custom headers directly.', caller[0,10]) params.merge!(custom_headers) end + part = Mail::Part.new(params) yield part if block_given? @parts << part @@ -476,6 +478,20 @@ module ActionMailer #:nodoc: part(params, &block) end + # Allow you to set assigns for your template: + # + # body :greetings => "Hi" + # + # Will make @greetings available in the template to be rendered. + def body(object=nil) + returning(super) do # Run deprecation hooks + if object.is_a?(Hash) + @assigns_set = true + object.each { |k, v| instance_variable_set(:"@#{k}", v) } + end + end + end + # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer # will be initialized according to the named method. If not, the mailer will # remain uninitialized (useful when you only need to invoke the "receive" @@ -523,6 +539,23 @@ module ActionMailer #:nodoc: private + # Render a message but does not set it as mail body. Useful for rendering + # data for part and attachments. + # + # Examples: + # + # render_message "special_message" + # render_message :template => "special_message" + # render_message :inline => "<%= 'Hi!' %>" + def render_message(object) + case object + when String + render_to_body(:template => object) + else + render_to_body(object) + end + end + # Set up the default values for the various instance variables of this # mailer. Subclasses may override this method to provide different # defaults. diff --git a/actionmailer/lib/action_mailer/deprecated_body.rb b/actionmailer/lib/action_mailer/deprecated_body.rb index 20b0989a85..5379b33a54 100644 --- a/actionmailer/lib/action_mailer/deprecated_body.rb +++ b/actionmailer/lib/action_mailer/deprecated_body.rb @@ -1,15 +1,13 @@ module ActionMailer # TODO Remove this module all together in a next release. Ensure that super - # hooks in ActionMailer::Base are removed as well. + # hooks and @assigns_set in ActionMailer::Base are removed as well. module DeprecatedBody - def self.included(base) - base.class_eval do - # Define the body of the message. This is either a Hash (in which case it - # specifies the variables to pass to the template when it is rendered), - # or a string, in which case it specifies the actual text of the message. - adv_attr_accessor :body - end - end + extend ActionMailer::AdvAttrAccessor + + # Define the body of the message. This is either a Hash (in which case it + # specifies the variables to pass to the template when it is rendered), + # or a string, in which case it specifies the actual text of the message. + adv_attr_accessor :body def initialize_defaults(method_name) @body ||= {} @@ -18,32 +16,28 @@ module ActionMailer def attachment(params, &block) if params[:body] ActiveSupport::Deprecation.warn('attachment :body => "string" is deprecated. To set the body of an attachment ' << - 'please use :data instead, like attachment :data => "string".', caller[0,10]) + 'please use :data instead, like attachment :data => "string"', caller[0,10]) params[:data] = params.delete(:body) end end def create_parts - if String === @body - ActiveSupport::Deprecation.warn('body is deprecated. To set the body with a text ' << - 'call render(:text => "body").', caller[0,10]) + if String === @body && !defined?(@assigns_set) + ActiveSupport::Deprecation.warn('body(String) is deprecated. To set the body with a text ' << + 'call render(:text => "body")', caller[0,10]) self.response_body = @body - elsif @body.is_a?(Hash) && !@body.empty? - ActiveSupport::Deprecation.warn('body is deprecated. To set assigns simply ' << - 'use instance variables', caller[0,10]) - @body.each { |k, v| instance_variable_set(:"@#{k}", v) } + elsif self.response_body + @body = self.response_body end end def render(*args) options = args.last.is_a?(Hash) ? args.last : {} if options[:body] - ActiveSupport::Deprecation.warn(':body is deprecated. To set assigns simply ' << - 'use instance variables', caller[0,1]) + ActiveSupport::Deprecation.warn(':body in render deprecated. Please call body ' << + 'with a hash instead', caller[0,1]) - options.delete(:body).each do |k, v| - instance_variable_set(:"@#{k}", v) - end + body options.delete(:body) end super diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index cd41739f1a..f87d9b2e5b 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -120,11 +120,11 @@ class TestMailer < ActionMailer::Base content_type "multipart/alternative" part "text/plain" do |p| - p.body = "blah" + p.body = render_message(:text => "blah") end part "text/html" do |p| - p.body = "<b>blah</b>" + p.body = render_message(:inline => "<%= content_tag(:b, 'blah') %>") end end @@ -301,7 +301,6 @@ class TestMailer < ActionMailer::Base render :text => "testing" end - # This tests body calls accepeting a hash, which is deprecated. def body_ivar(recipient) recipients recipient subject "Body as a local variable" @@ -1078,7 +1077,7 @@ EOF def test_return_path_with_create mail = TestMailer.create_return_path - assert_equal "another@somewhere.test", mail.return_path + assert_equal ["another@somewhere.test"], mail.return_path end def test_return_path_with_deliver @@ -1089,8 +1088,7 @@ EOF end def test_body_is_stored_as_an_ivar - mail = nil - ActiveSupport::Deprecation.silence { mail = TestMailer.create_body_ivar(@recipient) } + mail = TestMailer.create_body_ivar(@recipient) assert_equal "body: foo\nbar: baz", mail.body.to_s end diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 48725ad82a..3119ee498b 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -62,15 +62,19 @@ module AbstractController # Array[String]:: A list of all methods that should be considered # actions. def action_methods - @action_methods ||= + @action_methods ||= begin # All public instance methods of this class, including ancestors - public_instance_methods(true).map { |m| m.to_s }.to_set - - # Except for public instance methods of Base and its ancestors - internal_methods.map { |m| m.to_s } + - # Be sure to include shadowed public instance methods of this class - public_instance_methods(false).map { |m| m.to_s } - - # And always exclude explicitly hidden actions - hidden_actions + methods = public_instance_methods(true).map { |m| m.to_s }.to_set - + # Except for public instance methods of Base and its ancestors + internal_methods.map { |m| m.to_s } + + # Be sure to include shadowed public instance methods of this class + public_instance_methods(false).map { |m| m.to_s } - + # And always exclude explicitly hidden actions + hidden_actions + + # Clear out AS callback method pollution + methods.reject { |method| method =~ /_one_time_conditions/ } + end end # Returns the full controller name, underscored, without the ending Controller. @@ -116,68 +120,72 @@ module AbstractController self.class.controller_path end - private - # Returns true if the name can be considered an action. This can - # be overridden in subclasses to modify the semantics of what - # can be considered an action. - # - # ==== Parameters - # name<String>:: The name of an action to be tested - # - # ==== Returns - # TrueClass, FalseClass - def action_method?(name) - self.class.action_methods.include?(name) + def action_methods + self.class.action_methods end - # Call the action. Override this in a subclass to modify the - # behavior around processing an action. This, and not #process, - # is the intended way to override action dispatching. - def process_action(method_name, *args) - send_action(method_name, *args) - end + private + # Returns true if the name can be considered an action. This can + # be overridden in subclasses to modify the semantics of what + # can be considered an action. + # + # ==== Parameters + # name<String>:: The name of an action to be tested + # + # ==== Returns + # TrueClass, FalseClass + def action_method?(name) + self.class.action_methods.include?(name) + end - # Actually call the method associated with the action. Override - # this method if you wish to change how action methods are called, - # not to add additional behavior around it. For example, you would - # override #send_action if you want to inject arguments into the - # method. - alias send_action send - - # If the action name was not found, but a method called "action_missing" - # was found, #method_for_action will return "_handle_action_missing". - # This method calls #action_missing with the current action name. - def _handle_action_missing - action_missing(@_action_name) - end + # Call the action. Override this in a subclass to modify the + # behavior around processing an action. This, and not #process, + # is the intended way to override action dispatching. + def process_action(method_name, *args) + send_action(method_name, *args) + end - # Takes an action name and returns the name of the method that will - # handle the action. In normal cases, this method returns the same - # name as it receives. By default, if #method_for_action receives - # a name that is not an action, it will look for an #action_missing - # method and return "_handle_action_missing" if one is found. - # - # Subclasses may override this method to add additional conditions - # that should be considered an action. For instance, an HTTP controller - # with a template matching the action name is considered to exist. - # - # If you override this method to handle additional cases, you may - # also provide a method (like _handle_method_missing) to handle - # the case. - # - # If none of these conditions are true, and method_for_action - # returns nil, an ActionNotFound exception will be raised. - # - # ==== Parameters - # action_name<String>:: An action name to find a method name for - # - # ==== Returns - # String:: The name of the method that handles the action - # nil:: No method name could be found. Raise ActionNotFound. - def method_for_action(action_name) - if action_method?(action_name) then action_name - elsif respond_to?(:action_missing, true) then "_handle_action_missing" + # Actually call the method associated with the action. Override + # this method if you wish to change how action methods are called, + # not to add additional behavior around it. For example, you would + # override #send_action if you want to inject arguments into the + # method. + alias send_action send + + # If the action name was not found, but a method called "action_missing" + # was found, #method_for_action will return "_handle_action_missing". + # This method calls #action_missing with the current action name. + def _handle_action_missing + action_missing(@_action_name) + end + + # Takes an action name and returns the name of the method that will + # handle the action. In normal cases, this method returns the same + # name as it receives. By default, if #method_for_action receives + # a name that is not an action, it will look for an #action_missing + # method and return "_handle_action_missing" if one is found. + # + # Subclasses may override this method to add additional conditions + # that should be considered an action. For instance, an HTTP controller + # with a template matching the action name is considered to exist. + # + # If you override this method to handle additional cases, you may + # also provide a method (like _handle_method_missing) to handle + # the case. + # + # If none of these conditions are true, and method_for_action + # returns nil, an ActionNotFound exception will be raised. + # + # ==== Parameters + # action_name<String>:: An action name to find a method name for + # + # ==== Returns + # String:: The name of the method that handles the action + # nil:: No method name could be found. Raise ActionNotFound. + def method_for_action(action_name) + if action_method?(action_name) then action_name + elsif respond_to?(:action_missing, true) then "_handle_action_missing" + end end - end end end diff --git a/actionpack/lib/action_controller/deprecated/dispatcher.rb b/actionpack/lib/action_controller/deprecated/dispatcher.rb index 3da3c8ce7d..8c21e375dd 100644 --- a/actionpack/lib/action_controller/deprecated/dispatcher.rb +++ b/actionpack/lib/action_controller/deprecated/dispatcher.rb @@ -1,8 +1,5 @@ module ActionController class Dispatcher - cattr_accessor :prepare_each_request - self.prepare_each_request = false - class << self def before_dispatch(*args, &block) ActiveSupport::Deprecation.warn "ActionController::Dispatcher.before_dispatch is deprecated. " << @@ -18,7 +15,7 @@ module ActionController def to_prepare(*args, &block) ActiveSupport::Deprecation.warn "ActionController::Dispatcher.to_prepare is deprecated. " << - "Please use ActionDispatch::Callbacks.to_prepare instead.", caller + "Please use config.to_prepare instead", caller ActionDispatch::Callbacks.after(*args, &block) end diff --git a/actionpack/lib/action_controller/metal/cookies.rb b/actionpack/lib/action_controller/metal/cookies.rb index 5b51bd21d0..7aa687b52c 100644 --- a/actionpack/lib/action_controller/metal/cookies.rb +++ b/actionpack/lib/action_controller/metal/cookies.rb @@ -1,48 +1,4 @@ module ActionController #:nodoc: - # Cookies are read and written through ActionController#cookies. - # - # The cookies being read are the ones received along with the request, the cookies - # being written will be sent out with the response. Reading a cookie does not get - # the cookie object itself back, just the value it holds. - # - # Examples for writing: - # - # # Sets a simple session cookie. - # cookies[:user_name] = "david" - # - # # Sets a cookie that expires in 1 hour. - # cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now } - # - # Examples for reading: - # - # cookies[:user_name] # => "david" - # cookies.size # => 2 - # - # Example for deleting: - # - # cookies.delete :user_name - # - # Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie: - # - # cookies[:key] = { - # :value => 'a yummy cookie', - # :expires => 1.year.from_now, - # :domain => 'domain.com' - # } - # - # cookies.delete(:key, :domain => 'domain.com') - # - # The option symbols for setting cookies are: - # - # * <tt>:value</tt> - The cookie's value or list of values (as an array). - # * <tt>:path</tt> - The path for which this cookie applies. Defaults to the root - # of the application. - # * <tt>:domain</tt> - The domain for which this cookie applies. - # * <tt>:expires</tt> - The time at which this cookie expires, as a Time object. - # * <tt>:secure</tt> - Whether this cookie is a only transmitted to HTTPS servers. - # Default is +false+. - # * <tt>:httponly</tt> - Whether this cookie is accessible via scripting or - # only HTTP. Defaults to +false+. module Cookies extend ActiveSupport::Concern @@ -52,146 +8,10 @@ module ActionController #:nodoc: helper_method :cookies cattr_accessor :cookie_verifier_secret end - - protected - # Returns the cookie container, which operates as described above. + + private def cookies - @cookies ||= CookieJar.build(request, response) - end - end - - class CookieJar < Hash #:nodoc: - def self.build(request, response) - new.tap do |hash| - hash.update(request.cookies) - hash.response = response - end - end - - attr_accessor :response - - # Returns the value of the cookie by +name+, or +nil+ if no such cookie exists. - def [](name) - super(name.to_s) - end - - # Sets the cookie named +name+. The second argument may be the very cookie - # value, or a hash of options as documented above. - def []=(key, options) - if options.is_a?(Hash) - options.symbolize_keys! - value = options[:value] - else - value = options - options = { :value => value } + request.cookie_jar end - - super(key.to_s, value) - - options[:path] ||= "/" - response.set_cookie(key, options) - end - - # Removes the cookie on the client machine by setting the value to an empty string - # and setting its expiration date into the past. Like <tt>[]=</tt>, you can pass in - # an options hash to delete cookies with extra data such as a <tt>:path</tt>. - def delete(key, options = {}) - options.symbolize_keys! - options[:path] ||= "/" - value = super(key.to_s) - response.delete_cookie(key, options) - value - end - - # Returns a jar that'll automatically set the assigned cookies to have an expiration date 20 years from now. Example: - # - # cookies.permanent[:prefers_open_id] = true - # # => Set-Cookie: prefers_open_id=true; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT - # - # This jar is only meant for writing. You'll read permanent cookies through the regular accessor. - # - # This jar allows chaining with the signed jar as well, so you can set permanent, signed cookies. Examples: - # - # cookies.permanent.signed[:remember_me] = current_user.id - # # => Set-Cookie: discount=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT - def permanent - @permanent ||= PermanentCookieJar.new(self) - end - - # Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from - # the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed - # cookie was tampered with by the user (or a 3rd party), an ActiveSupport::MessageVerifier::InvalidSignature exception will - # be raised. - # - # This jar requires that you set a suitable secret for the verification on ActionController::Base.cookie_verifier_secret. - # - # Example: - # - # cookies.signed[:discount] = 45 - # # => Set-Cookie: discount=BAhpMg==--2c1c6906c90a3bc4fd54a51ffb41dffa4bf6b5f7; path=/ - # - # cookies.signed[:discount] # => 45 - def signed - @signed ||= SignedCookieJar.new(self) - end - end - - class PermanentCookieJar < CookieJar #:nodoc: - def initialize(parent_jar) - @parent_jar = parent_jar - end - - def []=(key, options) - if options.is_a?(Hash) - options.symbolize_keys! - else - options = { :value => options } - end - - options[:expires] = 20.years.from_now - @parent_jar[key] = options - end - - def signed - @signed ||= SignedCookieJar.new(self) - end - - def controller - @parent_jar.controller - end - - def method_missing(method, *arguments, &block) - @parent_jar.send(method, *arguments, &block) - end - end - - class SignedCookieJar < CookieJar #:nodoc: - def initialize(parent_jar) - unless ActionController::Base.cookie_verifier_secret - raise "You must set ActionController::Base.cookie_verifier_secret to use signed cookies" - end - - @parent_jar = parent_jar - @verifier = ActiveSupport::MessageVerifier.new(ActionController::Base.cookie_verifier_secret) - end - - def [](name) - @verifier.verify(@parent_jar[name]) - end - - def []=(key, options) - if options.is_a?(Hash) - options.symbolize_keys! - options[:value] = @verifier.generate(options[:value]) - else - options = { :value => @verifier.generate(options) } - end - - @parent_jar[key] = options - end - - def method_missing(method, *arguments, &block) - @parent_jar.send(method, *arguments, &block) - end end end diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb index 7222b7b2fa..876f778751 100644 --- a/actionpack/lib/action_controller/metal/instrumentation.rb +++ b/actionpack/lib/action_controller/metal/instrumentation.rb @@ -20,11 +20,7 @@ module ActionController result = super payload[:controller] = self.class.name payload[:action] = self.action_name - payload[:formats] = request.formats.map(&:to_s) - payload[:remote_ip] = request.remote_ip - payload[:method] = request.method payload[:status] = response.status - payload[:request_uri] = request.request_uri rescue "unknown" append_info_to_payload(payload) result end diff --git a/actionpack/lib/action_controller/metal/testing.rb b/actionpack/lib/action_controller/metal/testing.rb index c193a5eff4..d62269b9af 100644 --- a/actionpack/lib/action_controller/metal/testing.rb +++ b/actionpack/lib/action_controller/metal/testing.rb @@ -10,6 +10,9 @@ module ActionController @_response = response @_response.request = request ret = process(request.parameters[:action]) + if cookies = @_request.env['action_dispatch.cookies'] + cookies.write(@_response) + end @_response.body ||= self.response_body @_response.prepare! set_test_assigns diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 741101a210..7ea64c1923 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -23,7 +23,6 @@ module ActionController initializer "action_controller.initialize_routing" do |app| app.route_configuration_files << app.config.routes_configuration_file app.route_configuration_files << app.config.builtin_routes_configuration_file - app.reload_routes! end initializer "action_controller.initialize_framework_caches" do @@ -40,54 +39,5 @@ module ActionController ActionController::Base.view_paths = view_path if ActionController::Base.view_paths.blank? end - class MetalMiddlewareBuilder - def initialize(metals) - @metals = metals - end - - def new(app) - ActionDispatch::Cascade.new(@metals, app) - end - - def name - ActionDispatch::Cascade.name - end - alias_method :to_s, :name - end - - initializer "action_controller.initialize_metal" do |app| - metal_root = "#{Rails.root}/app/metal" - load_list = app.config.metals || Dir["#{metal_root}/**/*.rb"] - - metals = load_list.map { |metal| - metal = File.basename(metal.gsub("#{metal_root}/", ''), '.rb') - require_dependency metal - metal.camelize.constantize - }.compact - - middleware = MetalMiddlewareBuilder.new(metals) - app.config.middleware.insert_before(:"ActionDispatch::ParamsParser", middleware) - end - - # Prepare dispatcher callbacks and run 'prepare' callbacks - initializer "action_controller.prepare_dispatcher" do |app| - # TODO: This used to say unless defined?(Dispatcher). Find out why and fix. - # Notice that at this point, ActionDispatch::Callbacks were already loaded. - require 'rails/dispatcher' - ActionController::Dispatcher.prepare_each_request = true unless app.config.cache_classes - - unless app.config.cache_classes - # Setup dev mode route reloading - routes_last_modified = app.routes_changed_at - reload_routes = lambda do - unless app.routes_changed_at == routes_last_modified - routes_last_modified = app.routes_changed_at - app.reload_routes! - end - end - ActionDispatch::Callbacks.before { |callbacks| reload_routes.call } - end - end - end end diff --git a/actionpack/lib/action_controller/railties/subscriber.rb b/actionpack/lib/action_controller/railties/subscriber.rb index a9f5d16c58..6659e5df47 100644 --- a/actionpack/lib/action_controller/railties/subscriber.rb +++ b/actionpack/lib/action_controller/railties/subscriber.rb @@ -3,18 +3,13 @@ module ActionController class Subscriber < Rails::Subscriber def process_action(event) payload = event.payload - - info "\nProcessed #{payload[:controller]}##{payload[:action]} " \ - "to #{payload[:formats].join(', ')} (for #{payload[:remote_ip]} at #{event.time.to_s(:db)}) " \ - "[#{payload[:method].to_s.upcase}]" - info " Parameters: #{payload[:params].inspect}" unless payload[:params].blank? additions = ActionController::Base.log_process_action(payload) message = "Completed in %.0fms" % event.duration message << " (#{additions.join(" | ")})" unless additions.blank? - message << " | #{payload[:status]} [#{payload[:request_uri]}]\n\n" + message << " by #{payload[:controller]}##{payload[:action]} [#{payload[:status]}]" info(message) end diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 7b44212310..082562d921 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -43,8 +43,10 @@ module ActionDispatch autoload_under 'middleware' do autoload :Callbacks autoload :Cascade + autoload :Cookies autoload :Flash autoload :Head + autoload :Notifications autoload :ParamsParser autoload :Rescue autoload :ShowExceptions diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 65df9b1f03..f299306ff4 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -119,7 +119,7 @@ module ActionDispatch # :nodoc: def to_a assign_default_content_type_and_charset! handle_conditional_get! - self["Set-Cookie"] = @cookie.join("\n") + self["Set-Cookie"] = @cookie.join("\n") unless @cookie.blank? self["ETag"] = @etag if @etag super end diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb index 5ec406e134..d07841218a 100644 --- a/actionpack/lib/action_dispatch/middleware/callbacks.rb +++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb @@ -45,8 +45,6 @@ module ActionDispatch run_callbacks(:prepare) if @prepare_each_request @app.call(env) end - ensure - ActiveSupport::Notifications.instrument "action_dispatch.callback" end end end diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb new file mode 100644 index 0000000000..0dc03a1a7e --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -0,0 +1,216 @@ +module ActionDispatch + class Request + def cookie_jar + env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self) + end + end + + # Cookies are read and written through ActionController#cookies. + # + # The cookies being read are the ones received along with the request, the cookies + # being written will be sent out with the response. Reading a cookie does not get + # the cookie object itself back, just the value it holds. + # + # Examples for writing: + # + # # Sets a simple session cookie. + # cookies[:user_name] = "david" + # + # # Sets a cookie that expires in 1 hour. + # cookies[:login] = { :value => "XJ-122", :expires => 1.hour.from_now } + # + # Examples for reading: + # + # cookies[:user_name] # => "david" + # cookies.size # => 2 + # + # Example for deleting: + # + # cookies.delete :user_name + # + # Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie: + # + # cookies[:key] = { + # :value => 'a yummy cookie', + # :expires => 1.year.from_now, + # :domain => 'domain.com' + # } + # + # cookies.delete(:key, :domain => 'domain.com') + # + # The option symbols for setting cookies are: + # + # * <tt>:value</tt> - The cookie's value or list of values (as an array). + # * <tt>:path</tt> - The path for which this cookie applies. Defaults to the root + # of the application. + # * <tt>:domain</tt> - The domain for which this cookie applies. + # * <tt>:expires</tt> - The time at which this cookie expires, as a Time object. + # * <tt>:secure</tt> - Whether this cookie is a only transmitted to HTTPS servers. + # Default is +false+. + # * <tt>:httponly</tt> - Whether this cookie is accessible via scripting or + # only HTTP. Defaults to +false+. + class Cookies + class CookieJar < Hash #:nodoc: + def self.build(request) + new.tap do |hash| + hash.update(request.cookies) + end + end + + def initialize + @set_cookies = {} + @delete_cookies = {} + + super + end + + # Returns the value of the cookie by +name+, or +nil+ if no such cookie exists. + def [](name) + super(name.to_s) + end + + # Sets the cookie named +name+. The second argument may be the very cookie + # value, or a hash of options as documented above. + def []=(key, options) + if options.is_a?(Hash) + options.symbolize_keys! + value = options[:value] + else + value = options + options = { :value => value } + end + + value = super(key.to_s, value) + + options[:path] ||= "/" + @set_cookies[key] = options + value + end + + # Removes the cookie on the client machine by setting the value to an empty string + # and setting its expiration date into the past. Like <tt>[]=</tt>, you can pass in + # an options hash to delete cookies with extra data such as a <tt>:path</tt>. + def delete(key, options = {}) + options.symbolize_keys! + options[:path] ||= "/" + value = super(key.to_s) + @delete_cookies[key] = options + value + end + + # Returns a jar that'll automatically set the assigned cookies to have an expiration date 20 years from now. Example: + # + # cookies.permanent[:prefers_open_id] = true + # # => Set-Cookie: prefers_open_id=true; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT + # + # This jar is only meant for writing. You'll read permanent cookies through the regular accessor. + # + # This jar allows chaining with the signed jar as well, so you can set permanent, signed cookies. Examples: + # + # cookies.permanent.signed[:remember_me] = current_user.id + # # => Set-Cookie: discount=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT + def permanent + @permanent ||= PermanentCookieJar.new(self) + end + + # Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from + # the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed + # cookie was tampered with by the user (or a 3rd party), an ActiveSupport::MessageVerifier::InvalidSignature exception will + # be raised. + # + # This jar requires that you set a suitable secret for the verification on ActionController::Base.cookie_verifier_secret. + # + # Example: + # + # cookies.signed[:discount] = 45 + # # => Set-Cookie: discount=BAhpMg==--2c1c6906c90a3bc4fd54a51ffb41dffa4bf6b5f7; path=/ + # + # cookies.signed[:discount] # => 45 + def signed + @signed ||= SignedCookieJar.new(self) + end + + def write(response) + @set_cookies.each { |k, v| response.set_cookie(k, v) } + @delete_cookies.each { |k, v| response.delete_cookie(k, v) } + end + end + + class PermanentCookieJar < CookieJar #:nodoc: + def initialize(parent_jar) + @parent_jar = parent_jar + end + + def []=(key, options) + if options.is_a?(Hash) + options.symbolize_keys! + else + options = { :value => options } + end + + options[:expires] = 20.years.from_now + @parent_jar[key] = options + end + + def signed + @signed ||= SignedCookieJar.new(self) + end + + def controller + @parent_jar.controller + end + + def method_missing(method, *arguments, &block) + @parent_jar.send(method, *arguments, &block) + end + end + + class SignedCookieJar < CookieJar #:nodoc: + def initialize(parent_jar) + unless ActionController::Base.cookie_verifier_secret + raise "You must set ActionController::Base.cookie_verifier_secret to use signed cookies" + end + + @parent_jar = parent_jar + @verifier = ActiveSupport::MessageVerifier.new(ActionController::Base.cookie_verifier_secret) + end + + def [](name) + if value = @parent_jar[name] + @verifier.verify(value) + end + end + + def []=(key, options) + if options.is_a?(Hash) + options.symbolize_keys! + options[:value] = @verifier.generate(options[:value]) + else + options = { :value => @verifier.generate(options) } + end + + @parent_jar[key] = options + end + + def method_missing(method, *arguments, &block) + @parent_jar.send(method, *arguments, &block) + end + end + + def initialize(app) + @app = app + end + + def call(env) + status, headers, body = @app.call(env) + + if cookie_jar = env['action_dispatch.cookies'] + response = Rack::Response.new(body, status, headers) + cookie_jar.write(response) + response.to_a + else + [status, headers, body] + end + end + end +end diff --git a/actionpack/lib/action_dispatch/middleware/notifications.rb b/actionpack/lib/action_dispatch/middleware/notifications.rb new file mode 100644 index 0000000000..01d2cbb435 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/notifications.rb @@ -0,0 +1,24 @@ +module ActionDispatch + # Provide notifications in the middleware stack. Notice that for the before_dispatch + # and after_dispatch notifications, we just send the original env, so we don't pile + # up large env hashes in the queue. However, in exception cases, the whole env hash + # is actually useful, so we send it all. + class Notifications + def initialize(app) + @app = app + end + + def call(stack_env) + env = stack_env.dup + ActiveSupport::Notifications.instrument("action_dispatch.before_dispatch", :env => env) + + ActiveSupport::Notifications.instrument!("action_dispatch.after_dispatch", :env => env) do + @app.call(stack_env) + end + rescue Exception => exception + ActiveSupport::Notifications.instrument('action_dispatch.exception', + :env => stack_env, :exception => exception) + raise exception + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 10f04dcdf6..3bcd004e12 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -20,7 +20,7 @@ module ActionDispatch # * :exception - The exception raised; # class ShowExceptions - LOCALHOST = '127.0.0.1'.freeze + LOCALHOST = ['127.0.0.1', '::1'].freeze RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates') @@ -61,11 +61,8 @@ module ActionDispatch def call(env) @app.call(env) rescue Exception => exception - ActiveSupport::Notifications.instrument 'action_dispatch.show_exception', - :env => env, :exception => exception do - raise exception if env['action_dispatch.show_exceptions'] == false - render_exception(env, exception) - end + raise exception if env['action_dispatch.show_exceptions'] == false + render_exception(env, exception) end private @@ -88,7 +85,10 @@ module ActionDispatch def rescue_action_locally(request, exception) template = ActionView::Base.new([RESCUES_TEMPLATE_PATH], :request => request, - :exception => exception + :exception => exception, + :application_trace => application_trace(exception), + :framework_trace => framework_trace(exception), + :full_trace => full_trace(exception) ) file = "rescues/#{@@rescue_templates[exception.class.name]}.erb" body = template.render(:file => file, :layout => 'rescues/layout.erb') @@ -118,7 +118,7 @@ module ActionDispatch # True if the request came from localhost, 127.0.0.1. def local_request?(request) - request.remote_addr == LOCALHOST && request.remote_ip == LOCALHOST + LOCALHOST.any?{ |local_ip| request.remote_addr == local_ip && request.remote_ip == local_ip } end def status_code(exception) @@ -148,9 +148,21 @@ module ActionDispatch end end - def clean_backtrace(exception) + def application_trace(exception) + clean_backtrace(exception, :silent) + end + + def framework_trace(exception) + clean_backtrace(exception, :noise) + end + + def full_trace(exception) + clean_backtrace(exception, :all) + end + + def clean_backtrace(exception, *args) defined?(Rails) && Rails.respond_to?(:backtrace_cleaner) ? - Rails.backtrace_cleaner.clean(exception.backtrace) : + Rails.backtrace_cleaner.clean(exception.backtrace, *args) : exception.backtrace end diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb index 5224403dab..839df50999 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb @@ -11,13 +11,20 @@ clean_params.delete("controller") request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n") + + def debug_hash(hash) + hash.sort_by { |k, v| k.to_s }.map { |k, v| "#{k}: #{v.inspect}" }.join("\n") + end %> <h2 style="margin-top: 30px">Request</h2> <p><b>Parameters</b>: <pre><%=h request_dump %></pre></p> <p><a href="#" onclick="document.getElementById('session_dump').style.display='block'; return false;">Show session dump</a></p> -<div id="session_dump" style="display:none"><%= debug(@request.session.instance_variable_get("@data")) %></div> +<div id="session_dump" style="display:none"><pre><%= debug_hash @request.session %></pre></div> + +<p><a href="#" onclick="document.getElementById('env_dump').style.display='block'; return false;">Show env dump</a></p> +<div id="env_dump" style="display:none"><pre><%= debug_hash @request.env %></pre></div> <h2 style="margin-top: 30px">Response</h2> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb index 07b4919934..d18b162a93 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb @@ -1,8 +1,8 @@ <% traces = [ - ["Application Trace", @exception.application_backtrace], - ["Framework Trace", @exception.framework_backtrace], - ["Full Trace", @exception.clean_backtrace] + ["Application Trace", @application_trace], + ["Framework Trace", @framework_trace], + ["Full Trace", @full_trace] ] names = traces.collect {|name, trace| name} %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb index 693e56270a..bd6ffbab5d 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb @@ -4,7 +4,7 @@ in <%=h @request.parameters['controller'].humanize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %> <% end %> </h1> -<pre><%=h @exception.clean_message %></pre> +<pre><%=h @exception.message %></pre> <%= render :file => "rescues/_trace.erb" %> <%= render :file => "rescues/_request_and_response.erb" %> diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb new file mode 100644 index 0000000000..18978bfb39 --- /dev/null +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -0,0 +1,29 @@ +require "action_dispatch" +require "rails" + +module ActionDispatch + class Railtie < Rails::Railtie + plugin_name :action_dispatch + + require "action_dispatch/railties/subscriber" + subscriber ActionDispatch::Railties::Subscriber.new + + # Prepare dispatcher callbacks and run 'prepare' callbacks + initializer "action_dispatch.prepare_dispatcher" do |app| + # TODO: This used to say unless defined?(Dispatcher). Find out why and fix. + require 'rails/dispatcher' + + unless app.config.cache_classes + # Setup dev mode route reloading + routes_last_modified = app.routes_changed_at + reload_routes = lambda do + unless app.routes_changed_at == routes_last_modified + routes_last_modified = app.routes_changed_at + app.reload_routes! + end + end + ActionDispatch::Callbacks.before { |callbacks| reload_routes.call } + end + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/railties/subscriber.rb b/actionpack/lib/action_dispatch/railties/subscriber.rb new file mode 100644 index 0000000000..c08a844c6a --- /dev/null +++ b/actionpack/lib/action_dispatch/railties/subscriber.rb @@ -0,0 +1,17 @@ +module ActionDispatch + module Railties + class Subscriber < Rails::Subscriber + def before_dispatch(event) + request = Request.new(event.payload[:env]) + path = request.request_uri.inspect rescue "unknown" + + info "\n\nProcessing #{path} to #{request.formats.join(', ')} " << + "(for #{request.remote_ip} at #{event.time.to_s(:db)}) [#{request.method.to_s.upcase}]" + end + + def logger + ActionController::Base.logger + end + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 9aaa4355f2..811c287355 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -418,28 +418,12 @@ module ActionDispatch def resource(*resources, &block) options = resources.extract_options! - if resources.length > 1 - raise ArgumentError if block_given? - resources.each { |r| resource(r, options) } - return self - end - - if path_names = options.delete(:path_names) - scope(:resources_path_names => path_names) do - resource(resources, options) - end + if verify_common_behavior_for(:resource, resources, options, &block) return self end resource = SingletonResource.new(resources.pop, options) - if @scope[:scope_level] == :resources - nested do - resource(resource.name, options, &block) - end - return self - end - scope(:path => resource.name.to_s, :controller => resource.controller) do with_scope_level(:resource, resource) do yield if block_given? @@ -459,28 +443,12 @@ module ActionDispatch def resources(*resources, &block) options = resources.extract_options! - if resources.length > 1 - raise ArgumentError if block_given? - resources.each { |r| resources(r, options) } - return self - end - - if path_names = options.delete(:path_names) - scope(:resources_path_names => path_names) do - resources(resources, options) - end + if verify_common_behavior_for(:resources, resources, options, &block) return self end resource = Resource.new(resources.pop, options) - if @scope[:scope_level] == :resources - nested do - resources(resource.name, options, &block) - end - return self - end - scope(:path => resource.name.to_s, :controller => resource.controller) do with_scope_level(:resources, resource) do yield if block_given? @@ -595,6 +563,29 @@ module ActionDispatch path_names[name.to_sym] || name.to_s end + def verify_common_behavior_for(method, resources, options, &block) + if resources.length > 1 + resources.each { |r| send(method, r, options, &block) } + return true + end + + if path_names = options.delete(:path_names) + scope(:resources_path_names => path_names) do + send(method, resources.pop, options, &block) + end + return true + end + + if @scope[:scope_level] == :resources + nested do + send(method, resources.pop, options, &block) + end + return true + end + + false + end + def with_exclusive_name_prefix(prefix) begin old_name_prefix = @scope[:name_prefix] diff --git a/actionpack/lib/action_view/helpers/debug_helper.rb b/actionpack/lib/action_view/helpers/debug_helper.rb index 90863fca08..885945fde3 100644 --- a/actionpack/lib/action_view/helpers/debug_helper.rb +++ b/actionpack/lib/action_view/helpers/debug_helper.rb @@ -27,10 +27,10 @@ module ActionView def debug(object) begin Marshal::dump(object) - "<pre class='debug_dump'>#{h(object.to_yaml).gsub(" ", " ")}</pre>" + "<pre class='debug_dump'>#{h(object.to_yaml).gsub(" ", " ")}</pre>".html_safe! rescue Exception => e # errors from Marshal or YAML # Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback - "<code class='debug_dump'>#{h(object.inspect)}</code>" + "<code class='debug_dump'>#{h(object.inspect)}</code>".html_safe! end end end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 10913c0fdb..7b04638ccc 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -92,6 +92,7 @@ class ActionController::IntegrationTest < ActiveSupport::TestCase middleware.use "ActionDispatch::ShowExceptions" middleware.use "ActionDispatch::Callbacks" middleware.use "ActionDispatch::ParamsParser" + middleware.use "ActionDispatch::Cookies" middleware.use "ActionDispatch::Flash" middleware.use "ActionDispatch::Head" }.build(routes || ActionController::Routing::Routes) diff --git a/actionpack/test/activerecord/controller_runtime_test.rb b/actionpack/test/activerecord/controller_runtime_test.rb index 37c7738301..d6f7cd80ab 100644 --- a/actionpack/test/activerecord/controller_runtime_test.rb +++ b/actionpack/test/activerecord/controller_runtime_test.rb @@ -37,8 +37,8 @@ module ControllerRuntimeSubscriberTest get :show wait - assert_equal 2, @logger.logged(:info).size - assert_match /\(Views: [\d\.]+ms | ActiveRecord: [\d\.]+ms\)/, @logger.logged(:info)[1] + assert_equal 1, @logger.logged(:info).size + assert_match /\(Views: [\d\.]+ms | ActiveRecord: [\d\.]+ms\)/, @logger.logged(:info)[0] end class SyncSubscriberTest < ActionController::TestCase diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb index c8e8b3857e..f5ccef8aaf 100644 --- a/actionpack/test/controller/cookie_test.rb +++ b/actionpack/test/controller/cookie_test.rb @@ -54,12 +54,12 @@ class CookieTest < ActionController::TestCase cookies.permanent[:user_name] = "Jamie" head :ok end - + def set_signed_cookie cookies.signed[:user_id] = 45 head :ok end - + def set_permanent_signed_cookie cookies.permanent.signed[:remember_me] = 100 head :ok @@ -120,28 +120,6 @@ class CookieTest < ActionController::TestCase assert_equal({"user_name" => nil}, @response.cookies) end - def test_cookiejar_accessor - @request.cookies["user_name"] = "david" - @controller.request = @request - jar = ActionController::CookieJar.build(@controller.request, @controller.response) - assert_equal "david", jar["user_name"] - assert_equal nil, jar["something_else"] - end - - def test_cookiejar_accessor_with_array_value - @request.cookies["pages"] = %w{1 2 3} - @controller.request = @request - jar = ActionController::CookieJar.build(@controller.request, @controller.response) - assert_equal %w{1 2 3}, jar["pages"] - end - - def test_cookiejar_delete_removes_item_and_returns_its_value - @request.cookies["user_name"] = "david" - @controller.response = @response - jar = ActionController::CookieJar.build(@controller.request, @controller.response) - assert_equal "david", jar.delete("user_name") - end - def test_delete_cookie_with_path get :delete_cookie_with_path assert_cookie_header "user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT" @@ -157,19 +135,24 @@ class CookieTest < ActionController::TestCase assert_match /Jamie/, @response.headers["Set-Cookie"] assert_match %r(#{20.years.from_now.utc.year}), @response.headers["Set-Cookie"] end - + def test_signed_cookie get :set_signed_cookie assert_equal 45, @controller.send(:cookies).signed[:user_id] end - + + def test_accessing_nonexistant_signed_cookie_should_not_raise_an_invalid_signature + get :set_signed_cookie + assert_nil @controller.send(:cookies).signed[:non_existant_attribute] + end + def test_permanent_signed_cookie get :set_permanent_signed_cookie assert_match %r(#{20.years.from_now.utc.year}), @response.headers["Set-Cookie"] assert_equal 100, @controller.send(:cookies).signed[:remember_me] end - + private def assert_cookie_header(expected) header = @response.headers["Set-Cookie"] diff --git a/actionpack/test/controller/filter_params_test.rb b/actionpack/test/controller/filter_params_test.rb index d0635669c2..45949636c3 100644 --- a/actionpack/test/controller/filter_params_test.rb +++ b/actionpack/test/controller/filter_params_test.rb @@ -9,23 +9,6 @@ end class FilterParamTest < ActionController::TestCase tests FilterParamController - class MockLogger - attr_reader :logged - attr_accessor :level - - def initialize - @level = Logger::DEBUG - end - - def method_missing(method, *args) - @logged ||= [] - @logged << args.first unless block_given? - @logged << yield if block_given? - end - end - - setup :set_logger - def test_filter_parameters_must_have_one_word assert_raises RuntimeError do FilterParamController.filter_parameter_logging @@ -65,14 +48,4 @@ class FilterParamTest < ActionController::TestCase assert !FilterParamController.action_methods.include?('filter_parameters') assert_raise(NoMethodError) { @controller.filter_parameters([{'password' => '[FILTERED]'}]) } end - - private - - def set_logger - @controller.logger = MockLogger.new - end - - def logs - @logs ||= @controller.logger.logged.compact.map {|l| l.to_s.strip} - end end diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb index 85a2e7f44b..3c651ebebc 100644 --- a/actionpack/test/controller/flash_test.rb +++ b/actionpack/test/controller/flash_test.rb @@ -220,7 +220,7 @@ class FlashIntegrationTest < ActionController::IntegrationTest def with_test_route_set with_routing do |set| set.draw do |map| - match ':action', :to => ActionDispatch::Session::CookieStore.new(TestController, :key => SessionKey, :secret => SessionSecret) + match ':action', :to => ActionDispatch::Session::CookieStore.new(FlashIntegrationTest::TestController, :key => FlashIntegrationTest::SessionKey, :secret => FlashIntegrationTest::SessionSecret) end yield end diff --git a/actionpack/test/controller/new_base/base_test.rb b/actionpack/test/controller/new_base/base_test.rb index 1f9bf7f0fb..964780eaf2 100644 --- a/actionpack/test/controller/new_base/base_test.rb +++ b/actionpack/test/controller/new_base/base_test.rb @@ -3,6 +3,8 @@ require 'abstract_unit' # Tests the controller dispatching happy path module Dispatching class SimpleController < ActionController::Base + before_filter :authenticate + def index render :text => "success" end @@ -12,12 +14,20 @@ module Dispatching end def modify_response_body_twice - ret = (self.response_body = "success") + ret = (self.response_body = "success") self.response_body = "#{ret}!" end def modify_response_headers end + + def show_actions + render :text => "actions: #{action_methods.to_a.join(', ')}" + end + + protected + def authenticate + end end class EmptyController < ActionController::Base ; end @@ -64,5 +74,21 @@ module Dispatching assert_equal 'empty', EmptyController.controller_name assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name end + + test "action methods" do + assert_equal Set.new(%w( + modify_response_headers + modify_response_body_twice + index + modify_response_body + show_actions + )), SimpleController.action_methods + + assert_equal Set.new, EmptyController.action_methods + assert_equal Set.new, Submodule::ContainedEmptyController.action_methods + + get "/dispatching/simple/show_actions" + assert_body "actions: modify_response_headers, modify_response_body_twice, index, modify_response_body, show_actions" + end end end diff --git a/actionpack/test/controller/subscriber_test.rb b/actionpack/test/controller/subscriber_test.rb index ef1a325799..24132ee928 100644 --- a/actionpack/test/controller/subscriber_test.rb +++ b/actionpack/test/controller/subscriber_test.rb @@ -66,15 +66,10 @@ module ActionControllerSubscriberTest def test_process_action get :show wait - assert_equal 2, logs.size - assert_match /Processed\sAnother::SubscribersController#show/, logs[0] - end - - def test_process_action_formats - get :show - wait - assert_equal 2, logs.size - assert_match /text\/html/, logs[0] + assert_equal 1, logs.size + assert_match /Completed/, logs.first + assert_match /\[200\]/, logs.first + assert_match /Another::SubscribersController#show/, logs.first end def test_process_action_without_parameters @@ -87,23 +82,14 @@ module ActionControllerSubscriberTest get :show, :id => '10' wait - assert_equal 3, logs.size - assert_equal 'Parameters: {"id"=>"10"}', logs[1] + assert_equal 2, logs.size + assert_equal 'Parameters: {"id"=>"10"}', logs[0] end def test_process_action_with_view_runtime get :show wait - assert_match /\(Views: [\d\.]+ms\)/, logs[1] - end - - def test_process_action_with_status_and_request_uri - get :show - wait - last = logs.last - assert_match /Completed/, last - assert_match /200/, last - assert_match /another\/subscribers\/show/, last + assert_match /\(Views: [\d\.]+ms\)/, logs[0] end def test_process_action_with_filter_parameters @@ -112,7 +98,7 @@ module ActionControllerSubscriberTest get :show, :lifo => 'Pratik', :amount => '420', :step => '1' wait - params = logs[1] + params = logs[0] assert_match /"amount"=>"\[FILTERED\]"/, params assert_match /"lifo"=>"\[FILTERED\]"/, params assert_match /"step"=>"1"/, params @@ -122,7 +108,7 @@ module ActionControllerSubscriberTest get :redirector wait - assert_equal 3, logs.size + assert_equal 2, logs.size assert_equal "Redirected to http://foo.bar/", logs[0] end @@ -130,7 +116,7 @@ module ActionControllerSubscriberTest get :data_sender wait - assert_equal 3, logs.size + assert_equal 2, logs.size assert_match /Sent data omg\.txt/, logs[0] end @@ -138,7 +124,7 @@ module ActionControllerSubscriberTest get :file_sender wait - assert_equal 3, logs.size + assert_equal 2, logs.size assert_match /Sent file/, logs[0] assert_match /test\/fixtures\/company\.rb/, logs[0] end @@ -147,7 +133,7 @@ module ActionControllerSubscriberTest get :xfile_sender wait - assert_equal 3, logs.size + assert_equal 2, logs.size assert_match /Sent X\-Sendfile header/, logs[0] assert_match /test\/fixtures\/company\.rb/, logs[0] end @@ -157,7 +143,7 @@ module ActionControllerSubscriberTest get :with_fragment_cache wait - assert_equal 4, logs.size + assert_equal 3, logs.size assert_match /Exist fragment\? views\/foo/, logs[0] assert_match /Write fragment views\/foo/, logs[1] ensure @@ -169,7 +155,7 @@ module ActionControllerSubscriberTest get :with_page_cache wait - assert_equal 3, logs.size + assert_equal 2, logs.size assert_match /Write page/, logs[0] assert_match /\/index\.html/, logs[0] ensure diff --git a/actionpack/test/dispatch/callbacks_test.rb b/actionpack/test/dispatch/callbacks_test.rb index f3ea5209f4..9df882ce75 100644 --- a/actionpack/test/dispatch/callbacks_test.rb +++ b/actionpack/test/dispatch/callbacks_test.rb @@ -85,18 +85,6 @@ class DispatcherTest < Test::Unit::TestCase assert_equal 4, Foo.b end - def test_should_send_an_instrumentation_callback_for_async_processing - ActiveSupport::Notifications.expects(:instrument).with("action_dispatch.callback") - dispatch - end - - def test_should_send_an_instrumentation_callback_for_async_processing_even_on_failure - ActiveSupport::Notifications.notifier.expects(:publish) - assert_raise RuntimeError do - dispatch { |env| raise "OMG" } - end - end - private def dispatch(cache_classes = true, &block) diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb index 02f63f7006..4697fa3e2b 100644 --- a/actionpack/test/dispatch/response_test.rb +++ b/actionpack/test/dispatch/response_test.rb @@ -13,8 +13,7 @@ class ResponseTest < ActiveSupport::TestCase assert_equal({ "Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "max-age=0, private, must-revalidate", - "ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"', - "Set-Cookie" => "" + "ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"' }, headers) parts = [] @@ -30,8 +29,7 @@ class ResponseTest < ActiveSupport::TestCase assert_equal({ "Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "max-age=0, private, must-revalidate", - "ETag" => '"ebb5e89e8a94e9dd22abf5d915d112b2"', - "Set-Cookie" => "" + "ETag" => '"ebb5e89e8a94e9dd22abf5d915d112b2"' }, headers) end @@ -44,8 +42,7 @@ class ResponseTest < ActiveSupport::TestCase assert_equal 200, status assert_equal({ "Content-Type" => "text/html; charset=utf-8", - "Cache-Control" => "no-cache", - "Set-Cookie" => "" + "Cache-Control" => "no-cache" }, headers) parts = [] diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb index ab7b9bc31b..d2c1758af1 100644 --- a/actionpack/test/dispatch/session/cookie_store_test.rb +++ b/actionpack/test/dispatch/session/cookie_store_test.rb @@ -137,7 +137,7 @@ class CookieStoreTest < ActionController::IntegrationTest with_test_route_set do get '/no_session_access' assert_response :success - assert_equal "", headers['Set-Cookie'] + assert_equal nil, headers['Set-Cookie'] end end @@ -147,7 +147,7 @@ class CookieStoreTest < ActionController::IntegrationTest "fef868465920f415f2c0652d6910d3af288a0367" get '/no_session_access' assert_response :success - assert_equal "", headers['Set-Cookie'] + assert_equal nil, headers['Set-Cookie'] end end diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb index 951fb4a22e..def86c8323 100644 --- a/actionpack/test/dispatch/show_exceptions_test.rb +++ b/actionpack/test/dispatch/show_exceptions_test.rb @@ -53,19 +53,21 @@ class ShowExceptionsTest < ActionController::IntegrationTest test "rescue locally from a local request" do @app = ProductionApp - self.remote_addr = '127.0.0.1' + ['127.0.0.1', '::1'].each do |ip_address| + self.remote_addr = ip_address - get "/" - assert_response 500 - assert_match /puke/, body + get "/" + assert_response 500 + assert_match /puke/, body - get "/not_found" - assert_response 404 - assert_match /#{ActionController::UnknownAction.name}/, body + get "/not_found" + assert_response 404 + assert_match /#{ActionController::UnknownAction.name}/, body - get "/method_not_allowed" - assert_response 405 - assert_match /ActionController::MethodNotAllowed/, body + get "/method_not_allowed" + assert_response 405 + assert_match /ActionController::MethodNotAllowed/, body + end end test "localize public rescue message" do @@ -104,27 +106,4 @@ class ShowExceptionsTest < ActionController::IntegrationTest assert_response 405 assert_match /ActionController::MethodNotAllowed/, body end - - test "publishes notifications" do - # Wait pending notifications to be published - ActiveSupport::Notifications.notifier.wait - - @app, event = ProductionApp, nil - self.remote_addr = '127.0.0.1' - - ActiveSupport::Notifications.subscribe('action_dispatch.show_exception') do |*args| - event = args - end - - get "/" - assert_response 500 - assert_match /puke/, body - - ActiveSupport::Notifications.notifier.wait - - assert_equal 'action_dispatch.show_exception', event.first - assert_kind_of Hash, event.last[:env] - assert_equal 'GET', event.last[:env]["REQUEST_METHOD"] - assert_kind_of RuntimeError, event.last[:exception] - end end diff --git a/actionpack/test/dispatch/subscriber_test.rb b/actionpack/test/dispatch/subscriber_test.rb new file mode 100644 index 0000000000..a7f1a2659a --- /dev/null +++ b/actionpack/test/dispatch/subscriber_test.rb @@ -0,0 +1,112 @@ +require "abstract_unit" +require "rails/subscriber/test_helper" +require "action_dispatch/railties/subscriber" + +module DispatcherSubscriberTest + Boomer = lambda do |env| + req = ActionDispatch::Request.new(env) + case req.path + when "/" + [200, {}, []] + else + raise "puke!" + end + end + + App = ActionDispatch::Notifications.new(Boomer) + + def setup + Rails::Subscriber.add(:action_dispatch, ActionDispatch::Railties::Subscriber.new) + @app = App + super + + @events = [] + ActiveSupport::Notifications.subscribe do |*args| + @events << args + end + end + + def set_logger(logger) + ActionController::Base.logger = logger + end + + def test_publishes_notifications + get "/" + wait + + assert_equal 2, @events.size + before, after = @events + + assert_equal 'action_dispatch.before_dispatch', before[0] + assert_kind_of Hash, before[4][:env] + assert_equal 'GET', before[4][:env]["REQUEST_METHOD"] + + assert_equal 'action_dispatch.after_dispatch', after[0] + assert_kind_of Hash, after[4][:env] + assert_equal 'GET', after[4][:env]["REQUEST_METHOD"] + end + + def test_publishes_notifications_even_on_failures + begin + get "/puke" + rescue + end + + wait + + assert_equal 3, @events.size + before, after, exception = @events + + assert_equal 'action_dispatch.before_dispatch', before[0] + assert_kind_of Hash, before[4][:env] + assert_equal 'GET', before[4][:env]["REQUEST_METHOD"] + + assert_equal 'action_dispatch.after_dispatch', after[0] + assert_kind_of Hash, after[4][:env] + assert_equal 'GET', after[4][:env]["REQUEST_METHOD"] + + assert_equal 'action_dispatch.exception', exception[0] + assert_kind_of Hash, exception[4][:env] + assert_equal 'GET', exception[4][:env]["REQUEST_METHOD"] + assert_kind_of RuntimeError, exception[4][:exception] + end + + def test_subscriber_logs_notifications + get "/" + wait + + log = @logger.logged(:info).first + assert_equal 1, @logger.logged(:info).size + + assert_match %r{^Processing "/" to text/html}, log + assert_match %r{\(for 127\.0\.0\.1}, log + assert_match %r{\[GET\]}, log + end + + def test_subscriber_has_its_logged_flushed_after_request + assert_equal 0, @logger.flush_count + get "/" + wait + assert_equal 1, @logger.flush_count + end + + def test_subscriber_has_its_logged_flushed_even_after_busted_requests + assert_equal 0, @logger.flush_count + begin + get "/puke" + rescue + end + wait + assert_equal 1, @logger.flush_count + end + + class SyncSubscriberTest < ActionController::IntegrationTest + include Rails::Subscriber::SyncTestHelper + include DispatcherSubscriberTest + end + + class AsyncSubscriberTest < ActionController::IntegrationTest + include Rails::Subscriber::AsyncTestHelper + include DispatcherSubscriberTest + end +end
\ No newline at end of file diff --git a/actionpack/test/fixtures/reply.rb b/actionpack/test/fixtures/reply.rb index 04598437c2..19cba93673 100644 --- a/actionpack/test/fixtures/reply.rb +++ b/actionpack/test/fixtures/reply.rb @@ -1,5 +1,5 @@ class Reply < ActiveRecord::Base - named_scope :base + scope :base belongs_to :topic, :include => [:replies] belongs_to :developer diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 93935c0473..76e6ad93a7 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -169,9 +169,11 @@ module ActiveModel # If no +messsage+ is supplied, :invalid is assumed. # # If +message+ is a Symbol, it will be translated, using the appropriate scope (see translate_error). + # If +message+ is a Proc, it will be called, allowing for things like Time.now to be used within an error def add(attribute, message = nil, options = {}) message ||= :invalid message = generate_message(attribute, message, options) if message.is_a?(Symbol) + message = message.call if message.is_a?(Proc) self[attribute] << message end diff --git a/activemodel/lib/active_model/validations/validates.rb b/activemodel/lib/active_model/validations/validates.rb index 4c82a993ae..90b244228a 100644 --- a/activemodel/lib/active_model/validations/validates.rb +++ b/activemodel/lib/active_model/validations/validates.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/hash/slice' + module ActiveModel module Validations module ClassMethods diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb index 38a2a716a7..eb100d1c35 100644 --- a/activemodel/test/cases/validations_test.rb +++ b/activemodel/test/cases/validations_test.rb @@ -212,4 +212,12 @@ class ValidationsTest < ActiveModel::TestCase all_errors = t.errors.to_a assert_deprecated { assert_equal all_errors, t.errors.each_full{|err| err} } end + + def test_validation_with_message_as_proc + Topic.validates_presence_of(:title, :message => proc { "no blanks here".upcase }) + + t = Topic.new + assert !t.valid? + assert ["NO BLANKS HERE"], t.errors[:title] + end end diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 38bcf0c787..ffff0b7e09 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,15 @@ *Edge* +* Allow relations to be used as scope. + + class Item + scope :red, where(:colour => 'red') + end + + Item.red.limit(10) # Ten red items + +* Rename named_scope to scope. [Pratik Naik] + * Changed ActiveRecord::Base.store_full_sti_class to be true by default reflecting the previously announced Rails 3 default [DHH] * Add Relation#except. [Pratik Naik] diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 468a6cd9f8..ebf1a41e85 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1701,30 +1701,19 @@ module ActiveRecord end def construct_finder_arel_with_included_associations(options, join_dependency) - relation = unscoped + relation = scoped for association in join_dependency.join_associations relation = association.join_relation(relation) end - relation = relation.joins(options[:joins]). - select(column_aliases(join_dependency)). - group(options[:group]). - having(options[:having]). - order(options[:order]). - where(options[:conditions]). - from(options[:from]) + relation = relation.apply_finder_options(options).select(column_aliases(join_dependency)) - scoped_relation = current_scoped_methods - scoped_relation_limit = scoped_relation.taken if scoped_relation - - relation = current_scoped_methods.except(:limit).merge(relation) if current_scoped_methods - - if !using_limitable_reflections?(join_dependency.reflections) && ((scoped_relation && scoped_relation.taken) || options[:limit]) + if !using_limitable_reflections?(join_dependency.reflections) && relation.limit_value relation = relation.where(construct_arel_limited_ids_condition(options, join_dependency)) end - relation = relation.limit(options[:limit] || scoped_relation_limit) if using_limitable_reflections?(join_dependency.reflections) + relation = relation.except(:limit, :offset) unless using_limitable_reflections?(join_dependency.reflections) relation end @@ -1752,23 +1741,14 @@ module ActiveRecord end def construct_finder_sql_for_association_limiting(options, join_dependency) - relation = unscoped + relation = scoped for association in join_dependency.join_associations relation = association.join_relation(relation) end - relation = relation.joins(options[:joins]). - where(options[:conditions]). - group(options[:group]). - having(options[:having]). - order(options[:order]). - limit(options[:limit]). - offset(options[:offset]). - from(options[:from]) - - relation = current_scoped_methods.except(:select, :includes, :eager_load).merge(relation) if current_scoped_methods - relation = relation.select(connection.distinct("#{connection.quote_table_name table_name}.#{primary_key}", options[:order])) + relation = relation.apply_finder_options(options).except(:select) + relation = relation.select(connection.distinct("#{connection.quote_table_name table_name}.#{primary_key}", relation.order_values.join(", "))) relation.to_sql end diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 64dd5cf629..e9402d3547 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -403,8 +403,6 @@ module ActiveRecord else super end - elsif @reflection.klass.scopes.include?(method) - @reflection.klass.scopes[method].call(self, *args) else with_scope(construct_scope) do if block_given? diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index bd05d1014c..7f39a189e4 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -37,7 +37,7 @@ module ActiveRecord if force record.save! else - return false unless record.save(validate) + return false unless record.save(:validate => validate) end end diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index d3336cf2d2..146a6ca55f 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -58,7 +58,7 @@ module ActiveRecord def insert_record(record, force = false, validate = true) set_belongs_to_association_for(record) - force ? record.save! : record.save(validate) + force ? record.save! : record.save(:validate => validate) end # Deletes the records according to the <tt>:dependent</tt> option. diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 387b85aacd..bd2acd4340 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -60,7 +60,7 @@ module ActiveRecord if force record.save! else - return false unless record.save(validate) + return false unless record.save(:validate => validate) end end diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index e178cb4ef2..325a8aa7ec 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -116,14 +116,14 @@ module ActiveRecord # post = Post.find(1) # post.author.name = '' # post.save # => false - # post.errors # => #<ActiveRecord::Errors:0x174498c @errors={"author_name"=>["can't be blank"]}, @base=#<Post ...>> + # post.errors # => #<ActiveRecord::Errors:0x174498c @errors={"author.name"=>["can't be blank"]}, @base=#<Post ...>> # # No validations will be performed on the associated models when validations # are skipped for the parent: # # post = Post.find(1) # post.author.name = '' - # post.save(false) # => true + # post.save(:validate => false) # => true module AutosaveAssociation extend ActiveSupport::Concern @@ -302,7 +302,7 @@ module ActiveRecord association.send(:insert_record, record) end elsif autosave - saved = record.save(false) + saved = record.save(:validate => false) end raise ActiveRecord::Rollback if saved == false @@ -332,7 +332,7 @@ module ActiveRecord key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id if autosave != false && (new_record? || association.new_record? || association[reflection.primary_key_name] != key || autosave) association[reflection.primary_key_name] = key - saved = association.save(!autosave) + saved = association.save(:validate => !autosave) raise ActiveRecord::Rollback if !saved && autosave saved end @@ -355,7 +355,7 @@ module ActiveRecord if autosave && association.marked_for_destruction? association.destroy elsif autosave != false - saved = association.save(!autosave) if association.new_record? || autosave + saved = association.save(:validate => !autosave) if association.new_record? || autosave if association.updated? association_id = association.send(reflection.options[:primary_key] || :id) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 4ee9887186..06244d1132 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -2136,16 +2136,16 @@ module ActiveRecord #:nodoc: end # :call-seq: - # save(perform_validation = true) + # save(options) # # Saves the model. # # If the model is new a record gets created in the database, otherwise # the existing record gets updated. # - # If +perform_validation+ is true validations run. If any of them fail - # the action is cancelled and +save+ returns +false+. If the flag is - # false validations are bypassed altogether. See + # By default, save always run validations. If any of them fail the action + # is cancelled and +save+ returns +false+. However, if you supply + # :validate => false, validations are bypassed altogether. See # ActiveRecord::Validations for more information. # # There's a series of callbacks associated with +save+. If any of the @@ -2220,7 +2220,7 @@ module ActiveRecord #:nodoc: # in Base is replaced with this when the validations module is mixed in, which it is by default. def update_attribute(name, value) send(name.to_s + '=', value) - save(false) + save(:validate => false) end # Updates all the attributes from the passed-in Hash and saves the record. If the object is invalid, the saving will diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb index e4b3caab4e..8a44dc7df1 100644 --- a/activerecord/lib/active_record/calculations.rb +++ b/activerecord/lib/active_record/calculations.rb @@ -46,19 +46,19 @@ module ActiveRecord def count(*args) case args.size when 0 - construct_calculation_arel({}, current_scoped_methods).count + construct_calculation_arel.count when 1 if args[0].is_a?(Hash) options = args[0] distinct = options.has_key?(:distinct) ? options.delete(:distinct) : false - construct_calculation_arel(options, current_scoped_methods).count(options[:select], :distinct => distinct) + construct_calculation_arel(options).count(options[:select], :distinct => distinct) else - construct_calculation_arel({}, current_scoped_methods).count(args[0]) + construct_calculation_arel.count(args[0]) end when 2 column_name, options = args distinct = options.has_key?(:distinct) ? options.delete(:distinct) : false - construct_calculation_arel(options, current_scoped_methods).count(column_name, :distinct => distinct) + construct_calculation_arel(options).count(column_name, :distinct => distinct) else raise ArgumentError, "Unexpected parameters passed to count(): #{args.inspect}" end @@ -141,7 +141,7 @@ module ActiveRecord # Person.minimum(:age, :having => 'min(age) > 17', :group => :last_name) # Selects the minimum age for any family without any minors # Person.sum("2 * age") def calculate(operation, column_name, options = {}) - construct_calculation_arel(options, current_scoped_methods).calculate(operation, column_name, options.slice(:distinct)) + construct_calculation_arel(options).calculate(operation, column_name, options.slice(:distinct)) rescue ThrowResult 0 end @@ -151,60 +151,21 @@ module ActiveRecord options.assert_valid_keys(CALCULATIONS_OPTIONS) end - def construct_calculation_arel(options = {}, merge_with_relation = nil) + def construct_calculation_arel(options = {}) validate_calculation_options(options) options = options.except(:distinct) - merge_with_includes = merge_with_relation ? merge_with_relation.includes_values : [] + merge_with_includes = current_scoped_methods ? current_scoped_methods.includes_values : [] includes = (merge_with_includes + Array.wrap(options[:include])).uniq if includes.any? - merge_with_joins = merge_with_relation ? merge_with_relation.joins_values : [] + merge_with_joins = current_scoped_methods ? current_scoped_methods.joins_values : [] joins = (merge_with_joins + Array.wrap(options[:joins])).uniq join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, includes, construct_join(joins)) - construct_calculation_arel_with_included_associations(options, join_dependency, merge_with_relation) + construct_finder_arel_with_included_associations(options, join_dependency) else - relation = unscoped.apply_finder_options(options.slice(:joins, :conditions, :order, :limit, :offset, :group, :having)) - - if merge_with_relation - relation = merge_with_relation.except(:select, :order, :limit, :offset, :group, :from).merge(relation) - end - - from = merge_with_relation.from_value if merge_with_relation && merge_with_relation.from_value.present? - from = options[:from] if from.blank? && options[:from].present? - relation = relation.from(from) - - select = options[:select].presence || (merge_with_relation ? merge_with_relation.select_values.join(", ") : nil) - relation = relation.select(select) - - relation - end - end - - def construct_calculation_arel_with_included_associations(options, join_dependency, merge_with_relation = nil) - relation = unscoped - - for association in join_dependency.join_associations - relation = association.join_relation(relation) + scoped.apply_finder_options(options) end - - if merge_with_relation - relation.joins_values = (merge_with_relation.joins_values + relation.joins_values).uniq - relation.where_values = merge_with_relation.where_values - - merge_limit = merge_with_relation.taken - end - - relation = relation.apply_finder_options(options.slice(:joins, :group, :having, :order, :conditions, :from)). - select(column_aliases(join_dependency)) - - if !using_limitable_reflections?(join_dependency.reflections) && (merge_limit || options[:limit]) - relation = relation.where(construct_arel_limited_ids_condition(options, join_dependency)) - end - - relation = relation.limit(options[:limit] || merge_limit) if using_limitable_reflections?(join_dependency.reflections) - - relation end end diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index aecde5848c..1128286f2b 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -291,7 +291,7 @@ module ActiveRecord end def deprecated_callback_method(symbol) #:nodoc: - if respond_to?(symbol) + if respond_to?(symbol, true) ActiveSupport::Deprecation.warn("Overwriting #{symbol} in your models has been deprecated, please use Base##{symbol} :method_name instead") send(symbol) end diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb index 90fd700437..92030e5bfd 100644 --- a/activerecord/lib/active_record/named_scope.rb +++ b/activerecord/lib/active_record/named_scope.rb @@ -9,7 +9,7 @@ module ActiveRecord module ClassMethods # Returns a relation if invoked without any arguments. # - # posts = Post.scoped + # posts = Post.scoped # posts.size # Fires "select count(*) from posts" and returns the count # posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects # @@ -24,15 +24,9 @@ module ActiveRecord # You can define a scope that applies to all finders using ActiveRecord::Base.default_scope. def scoped(options = {}, &block) if options.present? - Scope.new(self, options, &block) + Scope.init(self, options, &block) else - current_scope = current_scoped_methods - - unless current_scope - unscoped.spawn - else - construct_finder_arel({}, current_scoped_methods) - end + current_scoped_methods ? unscoped.merge(current_scoped_methods) : unscoped.spawn end end @@ -44,11 +38,11 @@ module ActiveRecord # such as <tt>:conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions</tt>. # # class Shirt < ActiveRecord::Base - # named_scope :red, :conditions => {:color => 'red'} - # named_scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true] + # scope :red, :conditions => {:color => 'red'} + # scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true] # end - # - # The above calls to <tt>named_scope</tt> define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red, + # + # The above calls to <tt>scope</tt> define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red, # in effect, represents the query <tt>Shirt.find(:all, :conditions => {:color => 'red'})</tt>. # # Unlike <tt>Shirt.find(...)</tt>, however, the object returned by Shirt.red is not an Array; it resembles the association object @@ -74,7 +68,7 @@ module ActiveRecord # Named \scopes can also be procedural: # # class Shirt < ActiveRecord::Base - # named_scope :colored, lambda { |color| + # scope :colored, lambda { |color| # { :conditions => { :color => color } } # } # end @@ -84,7 +78,7 @@ module ActiveRecord # Named \scopes can also have extensions, just as with <tt>has_many</tt> declarations: # # class Shirt < ActiveRecord::Base - # named_scope :red, :conditions => {:color => 'red'} do + # scope :red, :conditions => {:color => 'red'} do # def dom_id # 'red_shirts' # end @@ -96,18 +90,23 @@ module ActiveRecord # <tt>proxy_options</tt> method on the proxy itself. # # class Shirt < ActiveRecord::Base - # named_scope :colored, lambda { |color| + # scope :colored, lambda { |color| # { :conditions => { :color => color } } # } # end # # expected_options = { :conditions => { :colored => 'red' } } # assert_equal expected_options, Shirt.colored('red').proxy_options - def named_scope(name, options = {}, &block) + def scope(name, options = {}, &block) name = name.to_sym + + if !scopes[name] && respond_to?(name, true) + raise ArgumentError, "Cannot define scope :#{name} because #{self.name}.#{name} method already exists." + end + scopes[name] = lambda do |parent_scope, *args| - Scope.new(parent_scope, case options - when Hash + Scope.init(parent_scope, case options + when Hash, Relation options when Proc options.call(*args) @@ -119,104 +118,90 @@ module ActiveRecord end end end - end - class Scope - attr_reader :proxy_scope, :proxy_options, :current_scoped_methods_when_defined - NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? many? respond_to?).to_set - [].methods.each do |m| - unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s) - delegate m, :to => :proxy_found - end + def named_scope(*args, &block) + ActiveSupport::Deprecation.warn("Base.named_scope has been deprecated, please use Base.scope instead", caller) + scope(*args, &block) end + end - delegate :scopes, :with_scope, :scoped_methods, :to => :proxy_scope + class Scope < Relation + attr_accessor :current_scoped_methods_when_defined - def initialize(proxy_scope, options, &block) - options ||= {} - [options[:extend]].flatten.each { |extension| extend extension } if options[:extend] - extend Module.new(&block) if block_given? - unless Scope === proxy_scope - @current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods) - end - @proxy_scope, @proxy_options = proxy_scope, options.except(:extend) - end + delegate :scopes, :with_scope, :with_exclusive_scope, :scoped_methods, :scoped, :to => :klass - def reload - load_found; self - end + def self.init(klass, options, &block) + relation = new(klass, klass.arel_table) - def first(*args) - if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash)) - proxy_found.first(*args) + scope = if options.is_a?(Hash) + klass.scoped.apply_finder_options(options.except(:extend)) else - find(:first, *args) + options ? klass.scoped.merge(options) : klass.scoped end - end - def last(*args) - if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash)) - proxy_found.last(*args) - else - find(:last, *args) - end - end + relation = relation.merge(scope) - def size - @found ? @found.length : count - end + Array.wrap(options[:extend]).each {|extension| relation.send(:extend, extension) } if options.is_a?(Hash) + relation.send(:extend, Module.new(&block)) if block_given? - def empty? - @found ? @found.empty? : count.zero? + relation.current_scoped_methods_when_defined = klass.send(:current_scoped_methods) + relation end - def respond_to?(method, include_private = false) - super || @proxy_scope.respond_to?(method, include_private) + def find(*args) + options = args.extract_options! + relation = options.present? ? apply_finder_options(options) : self + + case args.first + when :first, :last, :all + relation.send(args.first) + else + options.present? ? relation.find(*args) : super + end end - def any? - if block_given? - proxy_found.any? { |*block_args| yield(*block_args) } + def first(*args) + if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash)) + to_a.first(*args) else - !empty? + args.first.present? ? apply_finder_options(args.first).first : super end end - # Returns true if the named scope has more than 1 matching record. - def many? - if block_given? - proxy_found.many? { |*block_args| yield(*block_args) } + def last(*args) + if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash)) + to_a.last(*args) else - size > 1 + args.first.present? ? apply_finder_options(args.first).last : super end end - protected - def proxy_found - @found || load_found + def count(*args) + options = args.extract_options! + options.present? ? apply_finder_options(options).count(*args) : super + end + + def ==(other) + to_a == other.to_a end private + def method_missing(method, *args, &block) - if scopes.include?(method) - scopes[method].call(self, *args) - else - with_scope({:find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ? proxy_options[:conditions] : {}}, :reverse_merge) do - method = :new if method == :build - if current_scoped_methods_when_defined && !scoped_methods.include?(current_scoped_methods_when_defined) - with_scope current_scoped_methods_when_defined do - proxy_scope.send(method, *args, &block) - end + if klass.respond_to?(method) + with_scope(self) do + if current_scoped_methods_when_defined && !scoped_methods.include?(current_scoped_methods_when_defined) && !scopes.include?(method) + with_scope(current_scoped_methods_when_defined) { klass.send(method, *args, &block) } else - proxy_scope.send(method, *args, &block) + klass.send(method, *args, &block) end end + else + super end end - def load_found - @found = find(:all) - end end + end end diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index b39e064e45..88974dd786 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -428,7 +428,7 @@ namespace :db do task :create => :environment do raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations? require 'rails/generators' - require 'rails/generators/rails/session_migration/session_migration_generator' + require 'generators/rails/session_migration/session_migration_generator' Rails::Generators::SessionMigrationGenerator.start [ ENV["MIGRATION"] || "add_sessions_table" ] end diff --git a/activerecord/lib/active_record/railties/subscriber.rb b/activerecord/lib/active_record/railties/subscriber.rb index 7c2a10cf0f..fd873dbff8 100644 --- a/activerecord/lib/active_record/railties/subscriber.rb +++ b/activerecord/lib/active_record/railties/subscriber.rb @@ -12,7 +12,7 @@ module ActiveRecord name = color(name, :magenta, true) end - debug "#{name} #{sql}" + debug " #{name} #{sql}" end def odd? diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 85bf878416..e37e692a97 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -7,7 +7,7 @@ module ActiveRecord include FinderMethods, CalculationMethods, SpawnMethods, QueryMethods - delegate :length, :collect, :map, :each, :all?, :to => :to_a + delegate :length, :collect, :map, :each, :all?, :include?, :to => :to_a attr_reader :table, :klass @@ -20,6 +20,8 @@ module ActiveRecord with_create_scope { @klass.new(*args, &block) } end + alias build new + def create(*args, &block) with_create_scope { @klass.create(*args, &block) } end @@ -43,33 +45,12 @@ module ActiveRecord def to_a return @records if loaded? - find_with_associations = @eager_load_values.any? || (@includes_values.any? && references_eager_loaded_tables?) - - @records = if find_with_associations - begin - options = { - :select => @select_values.any? ? @select_values.join(", ") : nil, - :joins => arel.joins(arel), - :group => @group_values.any? ? @group_values.join(", ") : nil, - :order => order_clause, - :conditions => where_clause, - :limit => arel.taken, - :offset => arel.skipped, - :from => (arel.send(:from_clauses) if arel.send(:sources).present?) - } - - including = (@eager_load_values + @includes_values).uniq - join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, including, nil) - @klass.send(:find_with_associations, options, join_dependency) - rescue ThrowResult - [] - end - else - @klass.find_by_sql(arel.to_sql) - end + eager_loading = @eager_load_values.any? || (@includes_values.any? && references_eager_loaded_tables?) + + @records = eager_loading ? find_with_associations : @klass.find_by_sql(arel.to_sql) preload = @preload_values - preload += @includes_values unless find_with_associations + preload += @includes_values unless eager_loading preload.each {|associations| @klass.send(:preload_associations, @records, associations) } # @readonly_value is true only if set explicity. @implicit_readonly is true if there are JOINS and no explicit SELECT. @@ -124,12 +105,13 @@ module ActiveRecord end def reload - @loaded = false reset + to_a # force reload + self end def reset - @first = @last = @to_sql = @order_clause = @scope_for_create = @arel = nil + @first = @last = @to_sql = @order_clause = @scope_for_create = @arel = @loaded = nil @records = [] self end @@ -172,6 +154,8 @@ module ActiveRecord end end + private + def with_create_scope @klass.send(:with_scope, :create => scope_for_create, :find => {}) { yield } end @@ -180,10 +164,6 @@ module ActiveRecord arel.send(:where_clauses).join(join_string) end - def order_clause - @order_clause ||= arel.send(:order_clauses).join(', ') - end - def references_eager_loaded_tables? joined_tables = (tables_in_string(arel.joins(arel)) + [table.name, table.table_alias]).compact.uniq (tables_in_string(to_sql) - joined_tables).any? diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 3668b0997f..980c5796f3 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -44,6 +44,42 @@ module ActiveRecord protected + def find_with_associations + including = (@eager_load_values + @includes_values).uniq + join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, including, nil) + rows = construct_relation_for_association_find(join_dependency).to_a + join_dependency.instantiate(rows) + rescue ThrowResult + [] + end + + def construct_relation_for_association_find(join_dependency) + relation = except(:includes, :eager_load, :preload, :select).select(@klass.send(:column_aliases, join_dependency)) + + for association in join_dependency.join_associations + relation = association.join_relation(relation) + end + + limitable_reflections = @klass.send(:using_limitable_reflections?, join_dependency.reflections) + + if !limitable_reflections && relation.limit_value + limited_id_condition = construct_limited_ids_condition(relation.except(:select)) + relation = relation.where(limited_id_condition) + end + + relation = relation.except(:limit, :offset) unless limitable_reflections + + relation + end + + def construct_limited_ids_condition(relation) + orders = relation.order_values.join(", ") + values = @klass.connection.distinct("#{@klass.connection.quote_table_name @klass.table_name}.#{@klass.primary_key}", orders) + + ids_array = relation.select(values).collect {|row| row[@klass.primary_key]} + ids_array.empty? ? raise(ThrowResult) : primary_key.in(ids_array) + end + def find_by_attributes(match, attributes, *args) conditions = attributes.inject({}) {|h, a| h[a] = args[attributes.index(a)]; h} result = where(conditions).send(match.finder) diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 6b7d941350..9e855209f9 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -24,7 +24,8 @@ module ActiveRecord case value when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope - attribute.in(value) + values = value.to_a + values.any? ? attribute.in(values) : attribute.eq(nil) when Range # TODO : Arel should handle ranges with excluded end. if value.exclude_end? diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index f4abaae43e..d5b13c6100 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -1,7 +1,7 @@ module ActiveRecord module SpawnMethods def spawn(arel_table = self.table) - relation = Relation.new(@klass, arel_table) + relation = self.class.new(@klass, arel_table) (Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).each do |query_method| relation.send(:"#{query_method}_values=", send(:"#{query_method}_values")) @@ -15,11 +15,10 @@ module ActiveRecord end def merge(r) - if r.klass != @klass - raise ArgumentError, "Cannot merge a #{r.klass.name}(##{r.klass.object_id}) relation with #{@klass.name}(##{@klass.object_id}) relation" - end + merged_relation = spawn + return merged_relation unless r - merged_relation = spawn.eager_load(r.eager_load_values).preload(r.preload_values).includes(r.includes_values) + merged_relation = merged_relation.eager_load(r.eager_load_values).preload(r.preload_values).includes(r.includes_values) merged_relation.readonly_value = r.readonly_value unless r.readonly_value.nil? merged_relation.limit_value = r.limit_value if r.limit_value.present? @@ -33,7 +32,7 @@ module ActiveRecord from(r.from_value). having(r.having_values) - merged_relation.order_values = Array.wrap(order_values) + Array.wrap(r.order_values) + merged_relation.order_values = r.order_values if r.order_values.present? merged_relation.create_with_value = @create_with_value @@ -61,7 +60,7 @@ module ActiveRecord alias :& :merge def except(*skips) - result = Relation.new(@klass, table) + result = self.class.new(@klass, table) (Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).each do |method| result.send(:"#{method}_values=", send(:"#{method}_values")) unless skips.include?(method) @@ -75,7 +74,7 @@ module ActiveRecord end def only(*onlies) - result = Relation.new(@klass, table) + result = self.class.new(@klass, table) onlies.each do |only| if (Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).include?(only) @@ -94,9 +93,10 @@ module ActiveRecord :order, :select, :readonly, :group, :having, :from, :lock ] def apply_finder_options(options) - options.assert_valid_keys(VALID_FIND_OPTIONS) - relation = spawn + return relation unless options + + options.assert_valid_keys(VALID_FIND_OPTIONS) relation = relation.joins(options[:joins]). where(options[:conditions]). diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index 4f8ccdd40e..cf0fe8934d 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -192,8 +192,8 @@ module ActiveRecord with_transaction_returning_status(:destroy_without_transactions) end - def save_with_transactions(perform_validation = true) #:nodoc: - rollback_active_record_state! { with_transaction_returning_status(:save_without_transactions, perform_validation) } + def save_with_transactions(*args) #:nodoc: + rollback_active_record_state! { with_transaction_returning_status(:save_without_transactions, *args) } end def save_with_transactions! #:nodoc: diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index d5adcba3ba..a9743aa1ea 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -42,7 +42,17 @@ module ActiveRecord module InstanceMethods # The validation process on save can be skipped by passing false. The regular Base#save method is # replaced with this when the validations module is mixed in, which it is by default. - def save_with_validation(perform_validation = true) + def save_with_validation(options=nil) + perform_validation = case options + when NilClass + true + when Hash + options[:validate] != false + else + ActiveSupport::Deprecation.warn "save(#{options}) is deprecated, please give save(:validate => #{options}) instead", caller + options + end + if perform_validation && valid? || !perform_validation save_without_validation else diff --git a/railties/lib/rails/generators/active_record.rb b/activerecord/lib/generators/active_record.rb index c62f75c384..25b982f296 100644 --- a/railties/lib/rails/generators/active_record.rb +++ b/activerecord/lib/generators/active_record.rb @@ -8,6 +8,14 @@ module ActiveRecord class Base < Rails::Generators::NamedBase #:nodoc: include Rails::Generators::Migration + def self.source_root + @_ar_source_root ||= begin + if base_name && generator_name + File.expand_path(File.join(base_name, generator_name, 'templates'), File.dirname(__FILE__)) + end + end + end + protected # Implement the required interface for Rails::Generators::Migration. # diff --git a/railties/lib/rails/generators/active_record/migration/migration_generator.rb b/activerecord/lib/generators/active_record/migration/migration_generator.rb index f6159deeeb..7939977f72 100644 --- a/railties/lib/rails/generators/active_record/migration/migration_generator.rb +++ b/activerecord/lib/generators/active_record/migration/migration_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/active_record' +require 'generators/active_record' module ActiveRecord module Generators diff --git a/railties/lib/rails/generators/active_record/migration/templates/migration.rb b/activerecord/lib/generators/active_record/migration/templates/migration.rb index bbb7c53d86..bbb7c53d86 100644 --- a/railties/lib/rails/generators/active_record/migration/templates/migration.rb +++ b/activerecord/lib/generators/active_record/migration/templates/migration.rb diff --git a/railties/lib/rails/generators/active_record/model/model_generator.rb b/activerecord/lib/generators/active_record/model/model_generator.rb index 3e72fbeca8..2641083e0d 100644 --- a/railties/lib/rails/generators/active_record/model/model_generator.rb +++ b/activerecord/lib/generators/active_record/model/model_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/active_record' +require 'generators/active_record' module ActiveRecord module Generators diff --git a/railties/lib/rails/generators/active_record/model/templates/migration.rb b/activerecord/lib/generators/active_record/model/templates/migration.rb index 1f68487304..1f68487304 100644 --- a/railties/lib/rails/generators/active_record/model/templates/migration.rb +++ b/activerecord/lib/generators/active_record/model/templates/migration.rb diff --git a/railties/lib/rails/generators/active_record/model/templates/model.rb b/activerecord/lib/generators/active_record/model/templates/model.rb index 21ae29e9f2..21ae29e9f2 100644 --- a/railties/lib/rails/generators/active_record/model/templates/model.rb +++ b/activerecord/lib/generators/active_record/model/templates/model.rb diff --git a/railties/lib/rails/generators/active_record/observer/observer_generator.rb b/activerecord/lib/generators/active_record/observer/observer_generator.rb index c1c0e3f25b..a6b57423b8 100644 --- a/railties/lib/rails/generators/active_record/observer/observer_generator.rb +++ b/activerecord/lib/generators/active_record/observer/observer_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/active_record' +require 'generators/active_record' module ActiveRecord module Generators diff --git a/railties/lib/rails/generators/active_record/observer/templates/observer.rb b/activerecord/lib/generators/active_record/observer/templates/observer.rb index b9a3004161..b9a3004161 100644 --- a/railties/lib/rails/generators/active_record/observer/templates/observer.rb +++ b/activerecord/lib/generators/active_record/observer/templates/observer.rb diff --git a/railties/lib/rails/generators/active_record/session_migration/session_migration_generator.rb b/activerecord/lib/generators/active_record/session_migration/session_migration_generator.rb index afcda2a98a..59c4792066 100644 --- a/railties/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +++ b/activerecord/lib/generators/active_record/session_migration/session_migration_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/active_record' +require 'generators/active_record' module ActiveRecord module Generators diff --git a/railties/lib/rails/generators/active_record/session_migration/templates/migration.rb b/activerecord/lib/generators/active_record/session_migration/templates/migration.rb index 919822af7b..919822af7b 100644 --- a/railties/lib/rails/generators/active_record/session_migration/templates/migration.rb +++ b/activerecord/lib/generators/active_record/session_migration/templates/migration.rb diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index cc36a6dc5b..cc5460ddb7 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -805,7 +805,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase def test_should_still_allow_to_bypass_validations_on_the_associated_model @pirate.catchphrase = '' @pirate.ship.name = '' - @pirate.save(false) + @pirate.save(:validate => false) # Oracle saves empty string as NULL if current_adapter?(:OracleAdapter) assert_equal [nil, nil], [@pirate.reload.catchphrase, @pirate.ship.name] @@ -820,7 +820,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase @pirate.catchphrase = '' @pirate.ship.name = '' @pirate.ship.parts.each { |part| part.name = '' } - @pirate.save(false) + @pirate.save(:validate => false) values = [@pirate.reload.catchphrase, @pirate.ship.name, *@pirate.ship.parts.map(&:name)] # Oracle saves empty string as NULL @@ -917,7 +917,7 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase def test_should_still_allow_to_bypass_validations_on_the_associated_model @ship.pirate.catchphrase = '' @ship.name = '' - @ship.save(false) + @ship.save(:validate => false) # Oracle saves empty string as NULL if current_adapter?(:OracleAdapter) assert_equal [nil, nil], [@ship.reload.name, @ship.pirate.catchphrase] @@ -1029,7 +1029,7 @@ module AutosaveAssociationOnACollectionAssociationTests @pirate.catchphrase = '' @pirate.send(@association_name).each { |child| child.name = '' } - assert @pirate.save(false) + assert @pirate.save(:validate => false) # Oracle saves empty string as NULL if current_adapter?(:OracleAdapter) assert_equal [nil, nil, nil], [ @@ -1049,14 +1049,14 @@ module AutosaveAssociationOnACollectionAssociationTests def test_should_validation_the_associated_models_on_create assert_no_difference("#{ @association_name == :birds ? 'Bird' : 'Parrot' }.count") do 2.times { @pirate.send(@association_name).build } - @pirate.save(true) + @pirate.save end end def test_should_allow_to_bypass_validations_on_the_associated_models_on_create assert_difference("#{ @association_name == :birds ? 'Bird' : 'Parrot' }.count", +2) do 2.times { @pirate.send(@association_name).build } - @pirate.save(false) + @pirate.save(:validate => false) end end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index aea6aed8d9..1441b4278d 100755 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1865,7 +1865,9 @@ class BasicsTest < ActiveRecord::TestCase end assert scoped_developers.include?(developers(:poor_jamis)) assert scoped_developers.include?(developers(:david)) - assert scoped_developers.include?(developers(:dev_10)) + assert ! scoped_developers.include?(developers(:jamis)) + assert_equal 3, scoped_developers.size + # Test without scoped find conditions to ensure we get the right thing developers = Developer.find(:all, :order => 'id', :limit => 1) assert scoped_developers.include?(developers(:david)) diff --git a/activerecord/test/cases/method_scoping_test.rb b/activerecord/test/cases/method_scoping_test.rb index 26aa3ed8d5..7ca5b5a988 100644 --- a/activerecord/test/cases/method_scoping_test.rb +++ b/activerecord/test/cases/method_scoping_test.rb @@ -608,7 +608,7 @@ class DefaultScopingTest < ActiveRecord::TestCase def test_default_scoping_with_threads 2.times do - Thread.new { assert_equal 'salary DESC', DeveloperOrderedBySalary.scoped.send(:order_clause) }.join + Thread.new { assert_equal ['salary DESC'], DeveloperOrderedBySalary.scoped.order_values }.join end end @@ -618,28 +618,28 @@ class DefaultScopingTest < ActiveRecord::TestCase klass.send :default_scope, {} # Scopes added on children should append to parent scope - assert klass.scoped.send(:order_clause).blank? + assert klass.scoped.order_values.blank? # Parent should still have the original scope - assert_equal 'salary DESC', DeveloperOrderedBySalary.scoped.send(:order_clause) + assert_equal ['salary DESC'], DeveloperOrderedBySalary.scoped.order_values end def test_method_scope - expected = Developer.find(:all, :order => 'name DESC, salary DESC').collect { |dev| dev.salary } + expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary } received = DeveloperOrderedBySalary.all_ordered_by_name.collect { |dev| dev.salary } assert_equal expected, received end def test_nested_scope - expected = Developer.find(:all, :order => 'name DESC, salary DESC').collect { |dev| dev.salary } + expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.salary } received = DeveloperOrderedBySalary.send(:with_scope, :find => { :order => 'name DESC'}) do DeveloperOrderedBySalary.find(:all).collect { |dev| dev.salary } end assert_equal expected, received end - def test_named_scope_order_appended_to_default_scope_order - expected = Developer.find(:all, :order => 'name DESC, salary DESC').collect { |dev| dev.name } + def test_named_scope_overwrites_default + expected = Developer.find(:all, :order => 'name DESC').collect { |dev| dev.name } received = DeveloperOrderedBySalary.by_name.find(:all).collect { |dev| dev.name } assert_equal expected, received end diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb index 5d9232bc52..3e2bd58f9a 100644 --- a/activerecord/test/cases/named_scope_test.rb +++ b/activerecord/test/cases/named_scope_test.rb @@ -31,7 +31,7 @@ class NamedScopeTest < ActiveRecord::TestCase def test_reload_expires_cache_of_found_items all_posts = Topic.base - all_posts.inspect + all_posts.all new_post = Topic.create! assert !all_posts.include?(new_post) @@ -48,14 +48,14 @@ class NamedScopeTest < ActiveRecord::TestCase end def test_scope_should_respond_to_own_methods_and_methods_of_the_proxy - assert Topic.approved.respond_to?(:proxy_found) + assert Topic.approved.respond_to?(:limit) assert Topic.approved.respond_to?(:count) assert Topic.approved.respond_to?(:length) end def test_respond_to_respects_include_private_parameter - assert !Topic.approved.respond_to?(:load_found) - assert Topic.approved.respond_to?(:load_found, true) + assert !Topic.approved.respond_to?(:with_create_scope) + assert Topic.approved.respond_to?(:with_create_scope, true) end def test_subclasses_inherit_scopes @@ -150,13 +150,13 @@ class NamedScopeTest < ActiveRecord::TestCase end def test_named_scopes_honor_current_scopes_from_when_defined - assert !Post.ranked_by_comments.limit(5).empty? - assert !authors(:david).posts.ranked_by_comments.limit(5).empty? - assert_not_equal Post.ranked_by_comments.limit(5), authors(:david).posts.ranked_by_comments.limit(5) + assert !Post.ranked_by_comments.limit_by(5).empty? + assert !authors(:david).posts.ranked_by_comments.limit_by(5).empty? + assert_not_equal Post.ranked_by_comments.limit_by(5), authors(:david).posts.ranked_by_comments.limit_by(5) assert_not_equal Post.top(5), authors(:david).posts.top(5) # Oracle sometimes sorts differently if WHERE condition is changed - assert_equal authors(:david).posts.ranked_by_comments.limit(5).sort_by(&:id), authors(:david).posts.top(5).sort_by(&:id) - assert_equal Post.ranked_by_comments.limit(5), Post.top(5) + assert_equal authors(:david).posts.ranked_by_comments.limit_by(5).to_a.sort_by(&:id), authors(:david).posts.top(5).to_a.sort_by(&:id) + assert_equal Post.ranked_by_comments.limit_by(5), Post.top(5) end def test_active_records_have_scope_named__all__ @@ -171,11 +171,6 @@ class NamedScopeTest < ActiveRecord::TestCase assert_equal Topic.find(:all, scope), Topic.scoped(scope) end - def test_proxy_options - expected_proxy_options = { :conditions => { :approved => true } } - assert_equal expected_proxy_options, Topic.approved.proxy_options - end - def test_first_and_last_should_support_find_options assert_equal Topic.base.first(:order => 'title'), Topic.base.find(:first, :order => 'title') assert_equal Topic.base.last(:order => 'title'), Topic.base.find(:last, :order => 'title') @@ -297,7 +292,7 @@ class NamedScopeTest < ActiveRecord::TestCase end def test_find_all_should_behave_like_select - assert_equal Topic.base.select(&:approved), Topic.base.find_all(&:approved) + assert_equal Topic.base.to_a.select(&:approved), Topic.base.to_a.find_all(&:approved) end def test_rand_should_select_a_random_object_from_proxy @@ -345,14 +340,14 @@ class NamedScopeTest < ActiveRecord::TestCase def test_chaining_should_use_latest_conditions_when_searching # Normal hash conditions - assert_equal Topic.where(:approved => true).to_a, Topic.rejected.approved.all.to_a - assert_equal Topic.where(:approved => false).to_a, Topic.approved.rejected.all.to_a + assert_equal Topic.where(:approved => true).to_a, Topic.rejected.approved.all + assert_equal Topic.where(:approved => false).to_a, Topic.approved.rejected.all # Nested hash conditions with same keys - assert_equal [posts(:sti_comments)], Post.with_special_comments.with_very_special_comments.all.to_a + assert_equal [posts(:sti_comments)], Post.with_special_comments.with_very_special_comments.all # Nested hash conditions with different keys - assert_equal [posts(:sti_comments)], Post.with_special_comments.with_post(4).all.to_a.uniq + assert_equal [posts(:sti_comments)], Post.with_special_comments.with_post(4).all.uniq end def test_named_scopes_batch_finders @@ -374,6 +369,16 @@ class NamedScopeTest < ActiveRecord::TestCase Comment.for_first_post.for_first_author.all end end + + def test_named_scopes_with_reserved_names + [:where, :with_scope].each do |protected_method| + assert_raises(ArgumentError) { Topic.scope protected_method } + end + end + + def test_deprecated_named_scope_method + assert_deprecated('named_scope has been deprecated') { Topic.named_scope :deprecated_named_scope } + end end class DynamicScopeMatchTest < ActiveRecord::TestCase diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb index 195889f1df..d34c9b4895 100644 --- a/activerecord/test/cases/relations_test.rb +++ b/activerecord/test/cases/relations_test.rb @@ -68,10 +68,12 @@ class RelationTest < ActiveRecord::TestCase assert topics.loaded? - topics.reload - assert ! topics.loaded? + original_size = topics.to_a.size + Topic.create! :title => 'fake' - assert_queries(1) { topics.to_a } + assert_queries(1) { topics.reload } + assert_equal original_size + 1, topics.size + assert topics.loaded? end def test_finding_with_conditions @@ -337,6 +339,11 @@ class RelationTest < ActiveRecord::TestCase assert_raises(ActiveRecord::RecordNotFound) { authors.find(['42', 43]) } end + def test_find_in_empty_array + authors = Author.scoped.where(:id => []) + assert authors.all.blank? + end + def test_exists davids = Author.where(:name => 'David') assert davids.exists? @@ -418,10 +425,6 @@ class RelationTest < ActiveRecord::TestCase end end - def test_invalid_merge - assert_raises(ArgumentError) { Post.scoped & Developer.scoped } - end - def test_count posts = Post.scoped diff --git a/activerecord/test/cases/validations_test.rb b/activerecord/test/cases/validations_test.rb index 3a1d5ae212..5aac0229cd 100644 --- a/activerecord/test/cases/validations_test.rb +++ b/activerecord/test/cases/validations_test.rb @@ -19,7 +19,7 @@ end class DeprecatedPerson < ActiveRecord::Base set_table_name 'people' - protected + private def validate errors[:name] << "always invalid" @@ -124,7 +124,15 @@ class ValidationsTest < ActiveRecord::TestCase def test_create_without_validation reply = WrongReply.new assert !reply.save - assert reply.save(false) + assert reply.save(:validate => false) + end + + def test_deprecated_create_without_validation + reply = WrongReply.new + assert !reply.save + assert_deprecated do + assert reply.save(false) + end end def test_create_without_validation_bang @@ -153,4 +161,21 @@ class ValidationsTest < ActiveRecord::TestCase topic = Topic.create("author_name" => "Dan Brown") assert_equal "Dan Brown", topic["author_name"] end + + def test_validate_is_deprecated_on_create + p = DeprecatedPerson.new + assert_deprecated do + assert !p.valid? + end + assert_equal ["always invalid", "invalid on create"], p.errors[:name] + end + + def test_validate_is_deprecated_on_update + p = DeprecatedPerson.new(:first_name => "David") + assert p.save(:validate => false) + assert_deprecated do + assert !p.valid? + end + assert_equal ["always invalid", "invalid on update"], p.errors[:name] + end end diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb index 399dea9f12..a8a99f6dce 100644 --- a/activerecord/test/models/comment.rb +++ b/activerecord/test/models/comment.rb @@ -1,7 +1,7 @@ class Comment < ActiveRecord::Base - named_scope :containing_the_letter_e, :conditions => "comments.body LIKE '%e%'" - named_scope :for_first_post, :conditions => { :post_id => 1 } - named_scope :for_first_author, + scope :containing_the_letter_e, :conditions => "comments.body LIKE '%e%'" + scope :for_first_post, :conditions => { :post_id => 1 } + scope :for_first_author, :joins => :post, :conditions => { "posts.author_id" => 1 } diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb index 7e93fda1eb..df5fd10b6b 100644 --- a/activerecord/test/models/company.rb +++ b/activerecord/test/models/company.rb @@ -45,7 +45,7 @@ class Firm < Company has_many :unvalidated_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :validate => false has_many :dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :destroy has_many :exclusively_dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => :delete_all - has_many :limited_clients, :class_name => "Client", :order => "id", :limit => 1 + has_many :limited_clients, :class_name => "Client", :limit => 1 has_many :clients_like_ms, :conditions => "name = 'Microsoft'", :class_name => "Client", :order => "id" has_many :clients_with_interpolated_conditions, :class_name => "Client", :conditions => 'rating > #{rating}' has_many :clients_like_ms_with_hash_conditions, :conditions => { :name => 'Microsoft' }, :class_name => "Client", :order => "id" @@ -91,10 +91,8 @@ class Firm < Company end class DependentFirm < Company - # added order by id as in fixtures there are two accounts for Rails Core - # Oracle tests were failing because of that as the second fixture was selected - has_one :account, :foreign_key => "firm_id", :dependent => :nullify, :order => "id" - has_many :companies, :foreign_key => 'client_of', :order => "id", :dependent => :nullify + has_one :account, :foreign_key => "firm_id", :dependent => :nullify + has_many :companies, :foreign_key => 'client_of', :dependent => :nullify end class Client < Company diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 058970336b..e7a1e110d7 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -43,7 +43,7 @@ class Developer < ActiveRecord::Base has_many :audit_logs - named_scope :jamises, :conditions => {:name => 'Jamis'} + scope :jamises, :conditions => {:name => 'Jamis'} validates_inclusion_of :salary, :in => 50000..200000 validates_length_of :name, :within => 3..20 @@ -81,7 +81,7 @@ end class DeveloperOrderedBySalary < ActiveRecord::Base self.table_name = 'developers' default_scope :order => 'salary DESC' - named_scope :by_name, :order => 'name DESC' + scope :by_name, :order => 'name DESC' def self.all_ordered_by_name with_scope(:find => { :order => 'name DESC' }) do diff --git a/activerecord/test/models/organization.rb b/activerecord/test/models/organization.rb index c85726169e..1da342a0bd 100644 --- a/activerecord/test/models/organization.rb +++ b/activerecord/test/models/organization.rb @@ -2,5 +2,5 @@ class Organization < ActiveRecord::Base has_many :member_details has_many :members, :through => :member_details - named_scope :clubs, { :from => 'clubs' } + scope :clubs, { :from => 'clubs' } end
\ No newline at end of file diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb index 57fa6418f1..2a73b1ee01 100644 --- a/activerecord/test/models/person.rb +++ b/activerecord/test/models/person.rb @@ -12,6 +12,6 @@ class Person < ActiveRecord::Base has_many :agents, :class_name => 'Person', :foreign_key => 'primary_contact_id' belongs_to :number1_fan, :class_name => 'Person' - named_scope :males, :conditions => { :gender => 'M' } - named_scope :females, :conditions => { :gender => 'F' } + scope :males, :conditions => { :gender => 'M' } + scope :females, :conditions => { :gender => 'F' } end diff --git a/activerecord/test/models/post.rb b/activerecord/test/models/post.rb index 7392515ec7..f48b35486c 100644 --- a/activerecord/test/models/post.rb +++ b/activerecord/test/models/post.rb @@ -1,8 +1,8 @@ class Post < ActiveRecord::Base - named_scope :containing_the_letter_a, :conditions => "body LIKE '%a%'" - named_scope :ranked_by_comments, :order => "comments_count DESC" - named_scope :limit, lambda {|limit| {:limit => limit} } - named_scope :with_authors_at_address, lambda { |address| { + scope :containing_the_letter_a, where("body LIKE '%a%'") + scope :ranked_by_comments, order("comments_count DESC") + scope :limit_by, lambda {|l| limit(l) } + scope :with_authors_at_address, lambda { |address| { :conditions => [ 'authors.author_address_id = ?', address.id ], :joins => 'JOIN authors ON authors.id = posts.author_id' } @@ -19,13 +19,13 @@ class Post < ActiveRecord::Base has_one :last_comment, :class_name => 'Comment', :order => 'id desc' - named_scope :with_special_comments, :joins => :comments, :conditions => {:comments => {:type => 'SpecialComment'} } - named_scope :with_very_special_comments, :joins => :comments, :conditions => {:comments => {:type => 'VerySpecialComment'} } - named_scope :with_post, lambda {|post_id| + scope :with_special_comments, :joins => :comments, :conditions => {:comments => {:type => 'SpecialComment'} } + scope :with_very_special_comments, joins(:comments).where(:comments => {:type => 'VerySpecialComment'}) + scope :with_post, lambda {|post_id| { :joins => :comments, :conditions => {:comments => {:post_id => post_id} } } } - has_many :comments, :order => "body" do + has_many :comments do def find_most_recent find(:first, :order => "id DESC") end @@ -73,7 +73,7 @@ class Post < ActiveRecord::Base has_many :impatient_people, :through => :skimmers, :source => :person def self.top(limit) - ranked_by_comments.limit(limit) + ranked_by_comments.limit_by(limit) end def self.reset_log diff --git a/activerecord/test/models/reply.rb b/activerecord/test/models/reply.rb index f1ba45b528..264a49b465 100644 --- a/activerecord/test/models/reply.rb +++ b/activerecord/test/models/reply.rb @@ -1,7 +1,7 @@ require 'models/topic' class Reply < Topic - named_scope :base + scope :base belongs_to :topic, :foreign_key => "parent_id", :counter_cache => true belongs_to :topic_with_primary_key, :class_name => "Topic", :primary_key => "title", :foreign_key => "parent_title", :counter_cache => "replies_count" diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb index baca4972cb..91fc7c9416 100644 --- a/activerecord/test/models/topic.rb +++ b/activerecord/test/models/topic.rb @@ -1,19 +1,19 @@ class Topic < ActiveRecord::Base - named_scope :base - named_scope :written_before, lambda { |time| + scope :base + scope :written_before, lambda { |time| if time { :conditions => ['written_on < ?', time] } end } - named_scope :approved, :conditions => {:approved => true} - named_scope :rejected, :conditions => {:approved => false} + scope :approved, :conditions => {:approved => true} + scope :rejected, :conditions => {:approved => false} - named_scope :by_lifo, :conditions => {:author_name => 'lifo'} + scope :by_lifo, :conditions => {:author_name => 'lifo'} - named_scope :approved_as_hash_condition, :conditions => {:topics => {:approved => true}} - named_scope 'approved_as_string', :conditions => {:approved => true} - named_scope :replied, :conditions => ['replies_count > 0'] - named_scope :anonymous_extension do + scope :approved_as_hash_condition, :conditions => {:topics => {:approved => true}} + scope 'approved_as_string', :conditions => {:approved => true} + scope :replied, :conditions => ['replies_count > 0'] + scope :anonymous_extension do def one 1 end @@ -33,8 +33,8 @@ class Topic < ActiveRecord::Base 2 end end - named_scope :named_extension, :extend => NamedExtension - named_scope :multiple_extensions, :extend => [MultipleExtensionTwo, MultipleExtensionOne] + scope :named_extension, :extend => NamedExtension + scope :multiple_extensions, :extend => [MultipleExtensionTwo, MultipleExtensionOne] has_many :replies, :dependent => :destroy, :foreign_key => "parent_id" has_many :replies_with_primary_key, :class_name => "Reply", :dependent => :destroy, :primary_key => "title", :foreign_key => "parent_title" diff --git a/activeresource/lib/active_resource/validations.rb b/activeresource/lib/active_resource/validations.rb index 67b69fa505..7b2382bd8c 100644 --- a/activeresource/lib/active_resource/validations.rb +++ b/activeresource/lib/active_resource/validations.rb @@ -58,9 +58,8 @@ module ActiveResource # person.save # => true (and person is now saved to the remote service) # module Validations - extend ActiveSupport::Concern + extend ActiveSupport::Concern include ActiveModel::Validations - extend ActiveModel::Validations::ClassMethods included do alias_method_chain :save, :validation @@ -68,7 +67,17 @@ module ActiveResource # Validate a resource and save (POST) it to the remote web service. # If any local validations fail - the save (POST) will not be attempted. - def save_with_validation(perform_validation = true) + def save_with_validation(options=nil) + perform_validation = case options + when Hash + options[:validate] != false + when NilClass + true + else + ActiveSupport::Deprecation.warn "save(#{options}) is deprecated, please give save(:validate => #{options}) instead", caller + options + end + # clear the remote validations so they don't interfere with the local # ones. Otherwise we get an endless loop and can never change the # fields so as to make the resource valid diff --git a/activeresource/test/cases/validations_test.rb b/activeresource/test/cases/validations_test.rb index c05f625fb7..82546424f2 100644 --- a/activeresource/test/cases/validations_test.rb +++ b/activeresource/test/cases/validations_test.rb @@ -30,6 +30,19 @@ class ValidationsTest < ActiveModel::TestCase assert_raise(ActiveResource::ResourceInvalid) { p.save! } end + def test_save_without_validation + p = new_project(:name => nil) + assert !p.save + assert p.save(:validate => false) + end + + def test_deprecated_save_without_validation + p = new_project(:name => nil) + assert !p.save + assert_deprecated do + assert p.save(false) + end + end def test_validate_callback # we have a callback ensuring the description is longer than three letters diff --git a/activesupport/lib/active_support/backtrace_cleaner.rb b/activesupport/lib/active_support/backtrace_cleaner.rb index 0e262c003e..6fab565646 100644 --- a/activesupport/lib/active_support/backtrace_cleaner.rb +++ b/activesupport/lib/active_support/backtrace_cleaner.rb @@ -9,7 +9,7 @@ module ActiveSupport # Example: # # bc = BacktraceCleaner.new - # bc.add_filter { |line| line.gsub(Rails.root, '') } + # bc.add_filter { |line| line.gsub(Rails.root, '') } # bc.add_silencer { |line| line =~ /mongrel|rubygems/ } # bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems # @@ -18,10 +18,19 @@ module ActiveSupport def initialize @filters, @silencers = [], [] end - + # Returns the backtrace after all filters and silencers has been run against it. Filters run first, then silencers. - def clean(backtrace) - silence(filter(backtrace)) + def clean(backtrace, kind = :silent) + filtered = filter(backtrace) + + case kind + when :silent + silence(filtered) + when :noise + noise(filtered) + else + filtered + end end # Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter. @@ -51,21 +60,28 @@ module ActiveSupport @silencers = [] end - private def filter(backtrace) @filters.each do |f| backtrace = backtrace.map { |line| f.call(line) } end - + backtrace end - + def silence(backtrace) @silencers.each do |s| backtrace = backtrace.reject { |line| s.call(line) } end - + + backtrace + end + + def noise(backtrace) + @silencers.each do |s| + backtrace = backtrace.select { |line| s.call(line) } + end + backtrace end end diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 6360a4614e..7213b24f2d 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -30,7 +30,7 @@ module ActiveSupport # # ActiveSupport::Cache.lookup_store(:memory_store) # # => returns a new ActiveSupport::Cache::MemoryStore object - # + # # ActiveSupport::Cache.lookup_store(:mem_cache_store) # # => returns a new ActiveSupport::Cache::MemCacheStore object # @@ -97,7 +97,7 @@ module ActiveSupport # Ruby objects, but don't count on every cache store to be able to do that. # # cache = ActiveSupport::Cache::MemoryStore.new - # + # # cache.read("city") # => nil # cache.write("city", "Duckburgh") # cache.read("city") # => "Duckburgh" @@ -139,7 +139,7 @@ module ActiveSupport # # cache.write("today", "Monday") # cache.fetch("today") # => "Monday" - # + # # cache.fetch("city") # => nil # cache.fetch("city") do # "Duckburgh" @@ -198,7 +198,7 @@ module ActiveSupport # You may also specify additional options via the +options+ argument. # The specific cache store implementation will decide what to do with # +options+. - # + # # For example, MemCacheStore supports the +:expires_in+ option, which # tells the memcached server to automatically expire the cache item after # a certain period: diff --git a/activesupport/lib/active_support/core_ext/exception.rb b/activesupport/lib/active_support/core_ext/exception.rb index b594fbae8e..ef801e713d 100644 --- a/activesupport/lib/active_support/core_ext/exception.rb +++ b/activesupport/lib/active_support/core_ext/exception.rb @@ -1,50 +1,3 @@ module ActiveSupport FrozenObjectError = RUBY_VERSION < '1.9' ? TypeError : RuntimeError end - -# TODO: Turn all this into using the BacktraceCleaner. -class Exception # :nodoc: - # Clean the paths contained in the message. - def self.clean_paths(string) - require 'pathname' unless defined? Pathname - string.gsub(%r{[\w. ]+(/[\w. ]+)+(\.rb)?(\b|$)}) do |path| - Pathname.new(path).cleanpath - end - end - - def clean_message - Exception.clean_paths(message) - end - - TraceSubstitutions = [] - FrameworkStart = /action_controller\/dispatcher\.rb/.freeze - FrameworkRegexp = /generated|vendor|dispatch|ruby|script\/\w+/.freeze - - def clean_backtrace - backtrace.collect do |line| - substituted = TraceSubstitutions.inject(line) do |result, (regexp, sub)| - result.gsub regexp, sub - end - Exception.clean_paths(substituted) - end - end - - def application_backtrace - before_framework_frame = nil - before_application_frame = true - - trace = clean_backtrace.reject do |line| - before_framework_frame ||= (line =~ FrameworkStart) - non_app_frame = (line =~ FrameworkRegexp) - before_application_frame = false unless non_app_frame - before_framework_frame || (non_app_frame && !before_application_frame) - end - - # If we didn't find any application frames, return an empty app trace. - before_application_frame ? [] : trace - end - - def framework_backtrace - clean_backtrace.grep FrameworkRegexp - end -end diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb index 3e96decb8c..a1383bb478 100644 --- a/activesupport/lib/active_support/notifications.rb +++ b/activesupport/lib/active_support/notifications.rb @@ -45,7 +45,7 @@ module ActiveSupport class << self attr_writer :notifier delegate :publish, :subscribe, :to => :notifier - delegate :instrument, :to => :instrumenter + delegate :instrument, :instrument!, :to => :instrumenter def notifier @notifier ||= Notifier.new diff --git a/activesupport/lib/active_support/notifications/instrumenter.rb b/activesupport/lib/active_support/notifications/instrumenter.rb index f3d877efe7..7c5b118ee3 100644 --- a/activesupport/lib/active_support/notifications/instrumenter.rb +++ b/activesupport/lib/active_support/notifications/instrumenter.rb @@ -20,6 +20,15 @@ module ActiveSupport result end + # The same as instrument, but sends the notification even if the yielded + # block raises an error. + def instrument!(name, payload={}) + time = Time.now + yield(payload) if block_given? + ensure + @notifier.publish(name, time, Time.now, @id, payload) + end + private def unique_id SecureRandom.hex(10) diff --git a/activesupport/test/core_ext/exception_test.rb b/activesupport/test/core_ext/exception_test.rb deleted file mode 100644 index e63842c0bd..0000000000 --- a/activesupport/test/core_ext/exception_test.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'abstract_unit' -require 'active_support/core_ext/exception' - -class ExceptionExtTests < Test::Unit::TestCase - - def get_exception(cls = RuntimeError, msg = nil, trace = nil) - begin raise cls, msg, (trace || caller) - rescue Exception => e # passed Exception - return e - end - end - - def setup - Exception::TraceSubstitutions.clear - end - - def test_clean_backtrace - Exception::TraceSubstitutions << [/\s*hidden.*/, ''] - e = get_exception RuntimeError, 'RAWR', ['bhal.rb', 'rawh hid den stuff is not here', 'almost all'] - assert_kind_of Exception, e - assert_equal ['bhal.rb', 'rawh hid den stuff is not here', 'almost all'], e.clean_backtrace - end - - def test_app_backtrace - Exception::TraceSubstitutions << [/\s*hidden.*/, ''] - e = get_exception RuntimeError, 'RAWR', ['bhal.rb', ' vendor/file.rb some stuff', 'almost all'] - assert_kind_of Exception, e - assert_equal ['bhal.rb', 'almost all'], e.application_backtrace - end - - def test_app_backtrace_with_before - Exception::TraceSubstitutions << [/\s*hidden.*/, ''] - e = get_exception RuntimeError, 'RAWR', ['vendor/file.rb some stuff', 'bhal.rb', ' vendor/file.rb some stuff', 'almost all'] - assert_kind_of Exception, e - assert_equal ['vendor/file.rb some stuff', 'bhal.rb', 'almost all'], e.application_backtrace - end - - def test_framework_backtrace_with_before - Exception::TraceSubstitutions << [/\s*hidden.*/, ''] - e = get_exception RuntimeError, 'RAWR', ['vendor/file.rb some stuff', 'bhal.rb', ' vendor/file.rb some stuff', 'almost all'] - assert_kind_of Exception, e - assert_equal ['vendor/file.rb some stuff', ' vendor/file.rb some stuff'], e.framework_backtrace - end - - def test_backtrace_should_clean_paths - Exception::TraceSubstitutions << [/\s*hidden.*/, ''] - e = get_exception RuntimeError, 'RAWR', ['a/b/c/../d/../../../bhal.rb', 'rawh hid den stuff is not here', 'almost all'] - assert_kind_of Exception, e - assert_equal ['bhal.rb', 'rawh hid den stuff is not here', 'almost all'], e.clean_backtrace - end - - def test_clean_message_should_clean_paths - Exception::TraceSubstitutions << [/\s*hidden.*/, ''] - e = get_exception RuntimeError, "I dislike a/z/x/../../b/y/../c", ['a/b/c/../d/../../../bhal.rb', 'rawh hid den stuff is not here', 'almost all'] - assert_kind_of Exception, e - assert_equal "I dislike a/b/c", e.clean_message - end - - def test_app_trace_should_be_empty_when_no_app_frames - Exception::TraceSubstitutions << [/\s*hidden.*/, ''] - e = get_exception RuntimeError, 'RAWR', ['vendor/file.rb some stuff', 'generated/bhal.rb', ' vendor/file.rb some stuff', 'generated/almost all'] - assert_kind_of Exception, e - assert_equal [], e.application_backtrace - end - - def test_frozen_error - assert_raise(ActiveSupport::FrozenObjectError) { "foo".freeze.gsub!(/oo/,'aa') } - end -end diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb index c3eb1a4eb5..c41d81fe7e 100644 --- a/activesupport/test/notifications_test.rb +++ b/activesupport/test/notifications_test.rb @@ -90,6 +90,22 @@ module Notifications drain end + def test_instrument_with_bang_returns_result_even_on_failure + begin + instrument!(:awesome, :payload => "notifications") do + raise "OMG" + end + flunk + rescue + end + + drain + + assert_equal 1, @events.size + assert_equal :awesome, @events.last.name + assert_equal Hash[:payload => "notifications"], @events.last.payload + end + def test_instrument_yields_the_paylod_for_further_modification assert_equal 2, instrument(:awesome) { |p| p[:result] = 1 + 1 } drain diff --git a/railties/bin/rails b/railties/bin/rails index b8b2d6188f..afcd9fd0be 100755 --- a/railties/bin/rails +++ b/railties/bin/rails @@ -22,6 +22,6 @@ ARGV << "--help" if ARGV.empty? require 'rails/generators' -require 'rails/generators/rails/app/app_generator' +require 'generators/rails/app/app_generator' Rails::Generators::AppGenerator.start diff --git a/railties/lib/rails/generators/erb.rb b/railties/lib/generators/erb.rb index d468d012dc..d468d012dc 100644 --- a/railties/lib/rails/generators/erb.rb +++ b/railties/lib/generators/erb.rb diff --git a/railties/lib/rails/generators/erb/controller/controller_generator.rb b/railties/lib/generators/erb/controller/controller_generator.rb index f8780d9c33..ab7b273662 100644 --- a/railties/lib/rails/generators/erb/controller/controller_generator.rb +++ b/railties/lib/generators/erb/controller/controller_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/erb' +require 'generators/erb' module Erb module Generators diff --git a/railties/lib/rails/generators/erb/controller/templates/view.html.erb b/railties/lib/generators/erb/controller/templates/view.html.erb index cd54d13d83..cd54d13d83 100644 --- a/railties/lib/rails/generators/erb/controller/templates/view.html.erb +++ b/railties/lib/generators/erb/controller/templates/view.html.erb diff --git a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb b/railties/lib/generators/erb/mailer/mailer_generator.rb index 5266259e2f..4ec2f4c9f4 100644 --- a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb +++ b/railties/lib/generators/erb/mailer/mailer_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/erb' +require 'generators/erb' module Erb module Generators diff --git a/railties/lib/rails/generators/erb/mailer/templates/view.erb b/railties/lib/generators/erb/mailer/templates/view.erb index fcce7bd805..fcce7bd805 100644 --- a/railties/lib/rails/generators/erb/mailer/templates/view.erb +++ b/railties/lib/generators/erb/mailer/templates/view.erb diff --git a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb b/railties/lib/generators/erb/scaffold/scaffold_generator.rb index de5b0e9c5d..846540476f 100644 --- a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb +++ b/railties/lib/generators/erb/scaffold/scaffold_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/erb' +require 'generators/erb' require 'rails/generators/resource_helpers' module Erb diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/generators/erb/scaffold/templates/_form.html.erb index 9c19a09616..9c19a09616 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb +++ b/railties/lib/generators/erb/scaffold/templates/_form.html.erb diff --git a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb b/railties/lib/generators/erb/scaffold/templates/edit.html.erb index 5bc507ffc8..5bc507ffc8 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb +++ b/railties/lib/generators/erb/scaffold/templates/edit.html.erb diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/generators/erb/scaffold/templates/index.html.erb index b5c7fd1e58..b5c7fd1e58 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb +++ b/railties/lib/generators/erb/scaffold/templates/index.html.erb diff --git a/railties/lib/rails/generators/erb/scaffold/templates/layout.html.erb b/railties/lib/generators/erb/scaffold/templates/layout.html.erb index 7aa049fe80..7aa049fe80 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/layout.html.erb +++ b/railties/lib/generators/erb/scaffold/templates/layout.html.erb diff --git a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb b/railties/lib/generators/erb/scaffold/templates/new.html.erb index 9a1c489331..9a1c489331 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb +++ b/railties/lib/generators/erb/scaffold/templates/new.html.erb diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/generators/erb/scaffold/templates/show.html.erb index 24f13fc0f8..24f13fc0f8 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb +++ b/railties/lib/generators/erb/scaffold/templates/show.html.erb diff --git a/railties/lib/rails/generators/rails/app/USAGE b/railties/lib/generators/rails/app/USAGE index 36d6061a59..36d6061a59 100644 --- a/railties/lib/rails/generators/rails/app/USAGE +++ b/railties/lib/generators/rails/app/USAGE diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/generators/rails/app/app_generator.rb index d58d245168..2e34992b3b 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/generators/rails/app/app_generator.rb @@ -5,7 +5,7 @@ require 'rails/version' unless defined?(Rails::VERSION) module Rails::Generators # We need to store the RAILS_DEV_PATH in a constant, otherwise the path # can change in Ruby 1.8.7 when we FileUtils.cd. - RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__)) + RAILS_DEV_PATH = File.expand_path("../../../../..", File.dirname(__FILE__)) class AppGenerator < Base DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db ) @@ -35,7 +35,7 @@ module Rails::Generators :desc => "Skip Prototype files" class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false, - :desc => "Skip Git ignores and keeps" + :desc => "Skip Git ignores and keeps" # Add bin/rails options class_option :version, :type => :boolean, :aliases => "-v", :group => :rails, @@ -87,7 +87,7 @@ module Rails::Generators end def create_boot_file - copy_file "config/boot.rb" + template "config/boot.rb" end def create_activerecord_files diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/generators/rails/app/templates/Gemfile index 7b5c89c3e2..7b5c89c3e2 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/generators/rails/app/templates/Gemfile diff --git a/railties/lib/rails/generators/rails/app/templates/README b/railties/lib/generators/rails/app/templates/README index 37ec8ea211..37ec8ea211 100644 --- a/railties/lib/rails/generators/rails/app/templates/README +++ b/railties/lib/generators/rails/app/templates/README diff --git a/railties/lib/rails/generators/rails/app/templates/Rakefile b/railties/lib/generators/rails/app/templates/Rakefile index c19ad0e945..c19ad0e945 100755 --- a/railties/lib/rails/generators/rails/app/templates/Rakefile +++ b/railties/lib/generators/rails/app/templates/Rakefile diff --git a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb b/railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb index 2cdf4eae54..2cdf4eae54 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb +++ b/railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb diff --git a/railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb b/railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb index de6be7945c..de6be7945c 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb +++ b/railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb diff --git a/railties/lib/rails/generators/rails/app/templates/app/models/.empty_directory b/railties/lib/generators/rails/app/templates/app/models/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/models/.empty_directory +++ b/railties/lib/generators/rails/app/templates/app/models/.empty_directory diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/.empty_directory b/railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/.empty_directory +++ b/railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru b/railties/lib/generators/rails/app/templates/config.ru index 2ab821e38d..2ab821e38d 100644 --- a/railties/lib/rails/generators/rails/app/templates/config.ru +++ b/railties/lib/generators/rails/app/templates/config.ru diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/generators/rails/app/templates/config/application.rb index 334820826f..334820826f 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/generators/rails/app/templates/config/application.rb diff --git a/railties/lib/rails/generators/rails/app/templates/config/boot.rb b/railties/lib/generators/rails/app/templates/config/boot.rb index 6de1725260..466e1e50ec 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/boot.rb +++ b/railties/lib/generators/rails/app/templates/config/boot.rb @@ -13,7 +13,9 @@ else require 'rubygems' end +<% unless options[:skip_activerecord] -%> require 'rails/all' + # To pick the frameworks you want, remove 'require "rails/all"' # and list the framework railties that you want: # @@ -22,4 +24,13 @@ require 'rails/all' # require "action_controller/railtie" # require "action_view/railtie" # require "action_mailer/railtie" -# require "active_resource/railtie"
\ No newline at end of file +# require "active_resource/railtie" +<% else -%> +# Pick the frameworks you want: +# require "active_record/railtie" +require "active_model/railtie" +require "action_controller/railtie" +require "action_view/railtie" +require "action_mailer/railtie" +require "active_resource/railtie" +<% end -%>
\ No newline at end of file diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml b/railties/lib/generators/rails/app/templates/config/databases/frontbase.yml index c0c3588be1..c0c3588be1 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml +++ b/railties/lib/generators/rails/app/templates/config/databases/frontbase.yml diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml b/railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml index a9716ddb44..a9716ddb44 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml +++ b/railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/generators/rails/app/templates/config/databases/mysql.yml index 6bf2f7b1fd..6bf2f7b1fd 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +++ b/railties/lib/generators/rails/app/templates/config/databases/mysql.yml diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml b/railties/lib/generators/rails/app/templates/config/databases/oracle.yml index a1883f6256..a1883f6256 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +++ b/railties/lib/generators/rails/app/templates/config/databases/oracle.yml diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/generators/rails/app/templates/config/databases/postgresql.yml index f600e054cf..f600e054cf 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +++ b/railties/lib/generators/rails/app/templates/config/databases/postgresql.yml diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml b/railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml index 025d62a8d8..025d62a8d8 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml +++ b/railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml diff --git a/railties/lib/rails/generators/rails/app/templates/config/environment.rb b/railties/lib/generators/rails/app/templates/config/environment.rb index 1684986a59..1684986a59 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environment.rb +++ b/railties/lib/generators/rails/app/templates/config/environment.rb diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/generators/rails/app/templates/config/environments/development.rb.tt index b10103b436..b10103b436 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +++ b/railties/lib/generators/rails/app/templates/config/environments/development.rb.tt diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/generators/rails/app/templates/config/environments/production.rb.tt index 543a40108c..543a40108c 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/generators/rails/app/templates/config/environments/production.rb.tt diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/generators/rails/app/templates/config/environments/test.rb.tt index 428fa35633..428fa35633 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +++ b/railties/lib/generators/rails/app/templates/config/environments/test.rb.tt diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb b/railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb index 839d4cde19..839d4cde19 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb +++ b/railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt b/railties/lib/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt index 451dbe1d1c..451dbe1d1c 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt +++ b/railties/lib/generators/rails/app/templates/config/initializers/cookie_verification_secret.rb.tt diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb b/railties/lib/generators/rails/app/templates/config/initializers/inflections.rb index d531b8bb82..d531b8bb82 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb +++ b/railties/lib/generators/rails/app/templates/config/initializers/inflections.rb diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb b/railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb index 72aca7e441..72aca7e441 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb +++ b/railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt b/railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt index baff704d3e..baff704d3e 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +++ b/railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt diff --git a/railties/lib/rails/generators/rails/app/templates/config/locales/en.yml b/railties/lib/generators/rails/app/templates/config/locales/en.yml index f265c068d8..f265c068d8 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/locales/en.yml +++ b/railties/lib/generators/rails/app/templates/config/locales/en.yml diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/generators/rails/app/templates/config/routes.rb index d6c0365c04..d6c0365c04 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb +++ b/railties/lib/generators/rails/app/templates/config/routes.rb diff --git a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb b/railties/lib/generators/rails/app/templates/db/seeds.rb index bc8695e6f0..bc8695e6f0 100644 --- a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb +++ b/railties/lib/generators/rails/app/templates/db/seeds.rb diff --git a/railties/lib/rails/generators/rails/app/templates/doc/README_FOR_APP b/railties/lib/generators/rails/app/templates/doc/README_FOR_APP index fe41f5cc24..fe41f5cc24 100644 --- a/railties/lib/rails/generators/rails/app/templates/doc/README_FOR_APP +++ b/railties/lib/generators/rails/app/templates/doc/README_FOR_APP diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/generators/rails/app/templates/gitignore index a4f05d101d..a4f05d101d 100644 --- a/railties/lib/rails/generators/rails/app/templates/gitignore +++ b/railties/lib/generators/rails/app/templates/gitignore diff --git a/railties/lib/rails/generators/rails/app/templates/public/404.html b/railties/lib/generators/rails/app/templates/public/404.html index 9a48320a5f..9a48320a5f 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/404.html +++ b/railties/lib/generators/rails/app/templates/public/404.html diff --git a/railties/lib/rails/generators/rails/app/templates/public/422.html b/railties/lib/generators/rails/app/templates/public/422.html index 83660ab187..83660ab187 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/422.html +++ b/railties/lib/generators/rails/app/templates/public/422.html diff --git a/railties/lib/rails/generators/rails/app/templates/public/500.html b/railties/lib/generators/rails/app/templates/public/500.html index b80307fc16..b80307fc16 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/500.html +++ b/railties/lib/generators/rails/app/templates/public/500.html diff --git a/railties/lib/rails/generators/rails/app/templates/public/favicon.ico b/railties/lib/generators/rails/app/templates/public/favicon.ico index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/favicon.ico +++ b/railties/lib/generators/rails/app/templates/public/favicon.ico diff --git a/railties/lib/rails/generators/rails/app/templates/public/images/rails.png b/railties/lib/generators/rails/app/templates/public/images/rails.png Binary files differindex d5edc04e65..d5edc04e65 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/images/rails.png +++ b/railties/lib/generators/rails/app/templates/public/images/rails.png diff --git a/railties/lib/rails/generators/rails/app/templates/public/index.html b/railties/lib/generators/rails/app/templates/public/index.html index b153ae392f..b153ae392f 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/index.html +++ b/railties/lib/generators/rails/app/templates/public/index.html diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/application.js b/railties/lib/generators/rails/app/templates/public/javascripts/application.js index fe4577696b..fe4577696b 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/application.js +++ b/railties/lib/generators/rails/app/templates/public/javascripts/application.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/controls.js b/railties/lib/generators/rails/app/templates/public/javascripts/controls.js index ca29aefdd1..ca29aefdd1 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/controls.js +++ b/railties/lib/generators/rails/app/templates/public/javascripts/controls.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js b/railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js index 07229f986f..07229f986f 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/dragdrop.js +++ b/railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/effects.js b/railties/lib/generators/rails/app/templates/public/javascripts/effects.js index 5a639d2dea..5a639d2dea 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/effects.js +++ b/railties/lib/generators/rails/app/templates/public/javascripts/effects.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js b/railties/lib/generators/rails/app/templates/public/javascripts/prototype.js index dfe8ab4e13..dfe8ab4e13 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js +++ b/railties/lib/generators/rails/app/templates/public/javascripts/prototype.js diff --git a/railties/lib/rails/generators/rails/app/templates/public/robots.txt b/railties/lib/generators/rails/app/templates/public/robots.txt index 085187fa58..085187fa58 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/robots.txt +++ b/railties/lib/generators/rails/app/templates/public/robots.txt diff --git a/railties/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory b/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/stylesheets/.empty_directory +++ b/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory diff --git a/railties/lib/rails/generators/rails/app/templates/script/about b/railties/lib/generators/rails/app/templates/script/about index 93fd007649..93fd007649 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/about +++ b/railties/lib/generators/rails/app/templates/script/about diff --git a/railties/lib/rails/generators/rails/app/templates/script/console.tt b/railties/lib/generators/rails/app/templates/script/console.tt index daba8ba2f1..daba8ba2f1 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/console.tt +++ b/railties/lib/generators/rails/app/templates/script/console.tt diff --git a/railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt b/railties/lib/generators/rails/app/templates/script/dbconsole.tt index a7f114a97f..a7f114a97f 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt +++ b/railties/lib/generators/rails/app/templates/script/dbconsole.tt diff --git a/railties/lib/rails/generators/rails/app/templates/script/destroy b/railties/lib/generators/rails/app/templates/script/destroy index adfa8e8426..adfa8e8426 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/destroy +++ b/railties/lib/generators/rails/app/templates/script/destroy diff --git a/railties/lib/rails/generators/rails/app/templates/script/generate b/railties/lib/generators/rails/app/templates/script/generate index 6fb8ad0395..6fb8ad0395 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/generate +++ b/railties/lib/generators/rails/app/templates/script/generate diff --git a/railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker b/railties/lib/generators/rails/app/templates/script/performance/benchmarker index 9647d8f10a..9647d8f10a 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker +++ b/railties/lib/generators/rails/app/templates/script/performance/benchmarker diff --git a/railties/lib/rails/generators/rails/app/templates/script/performance/profiler b/railties/lib/generators/rails/app/templates/script/performance/profiler index a5822042d2..a5822042d2 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/performance/profiler +++ b/railties/lib/generators/rails/app/templates/script/performance/profiler diff --git a/railties/lib/rails/generators/rails/app/templates/script/plugin b/railties/lib/generators/rails/app/templates/script/plugin index 1f1af6c880..1f1af6c880 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/plugin +++ b/railties/lib/generators/rails/app/templates/script/plugin diff --git a/railties/lib/rails/generators/rails/app/templates/script/runner b/railties/lib/generators/rails/app/templates/script/runner index 3354ed4a28..3354ed4a28 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/runner +++ b/railties/lib/generators/rails/app/templates/script/runner diff --git a/railties/lib/rails/generators/rails/app/templates/script/server.tt b/railties/lib/generators/rails/app/templates/script/server.tt index 4fd0cc7832..4fd0cc7832 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/server.tt +++ b/railties/lib/generators/rails/app/templates/script/server.tt diff --git a/railties/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory b/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/fixtures/.empty_directory +++ b/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory diff --git a/railties/lib/rails/generators/rails/app/templates/test/functional/.empty_directory b/railties/lib/generators/rails/app/templates/test/functional/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/functional/.empty_directory +++ b/railties/lib/generators/rails/app/templates/test/functional/.empty_directory diff --git a/railties/lib/rails/generators/rails/app/templates/test/integration/.empty_directory b/railties/lib/generators/rails/app/templates/test/integration/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/integration/.empty_directory +++ b/railties/lib/generators/rails/app/templates/test/integration/.empty_directory diff --git a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb b/railties/lib/generators/rails/app/templates/test/performance/browsing_test.rb index a3dc38d9e4..a3dc38d9e4 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb +++ b/railties/lib/generators/rails/app/templates/test/performance/browsing_test.rb diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb b/railties/lib/generators/rails/app/templates/test/test_helper.rb index 45b551fc7d..45b551fc7d 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb +++ b/railties/lib/generators/rails/app/templates/test/test_helper.rb diff --git a/railties/lib/rails/generators/rails/app/templates/test/unit/.empty_directory b/railties/lib/generators/rails/app/templates/test/unit/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/unit/.empty_directory +++ b/railties/lib/generators/rails/app/templates/test/unit/.empty_directory diff --git a/railties/lib/rails/generators/rails/controller/USAGE b/railties/lib/generators/rails/controller/USAGE index 6ed4b2edfc..6ed4b2edfc 100644 --- a/railties/lib/rails/generators/rails/controller/USAGE +++ b/railties/lib/generators/rails/controller/USAGE diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/generators/rails/controller/controller_generator.rb index 91470be833..91470be833 100644 --- a/railties/lib/rails/generators/rails/controller/controller_generator.rb +++ b/railties/lib/generators/rails/controller/controller_generator.rb diff --git a/railties/lib/rails/generators/rails/controller/templates/controller.rb b/railties/lib/generators/rails/controller/templates/controller.rb index cda2659e69..cda2659e69 100644 --- a/railties/lib/rails/generators/rails/controller/templates/controller.rb +++ b/railties/lib/generators/rails/controller/templates/controller.rb diff --git a/railties/lib/rails/generators/rails/generator/USAGE b/railties/lib/generators/rails/generator/USAGE index ca7d3f62d0..ca7d3f62d0 100644 --- a/railties/lib/rails/generators/rails/generator/USAGE +++ b/railties/lib/generators/rails/generator/USAGE diff --git a/railties/lib/rails/generators/rails/generator/generator_generator.rb b/railties/lib/generators/rails/generator/generator_generator.rb index 5b5d1884bc..5b5d1884bc 100644 --- a/railties/lib/rails/generators/rails/generator/generator_generator.rb +++ b/railties/lib/generators/rails/generator/generator_generator.rb diff --git a/railties/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt b/railties/lib/generators/rails/generator/templates/%file_name%_generator.rb.tt index d8757460e4..d8757460e4 100644 --- a/railties/lib/rails/generators/rails/generator/templates/%file_name%_generator.rb.tt +++ b/railties/lib/generators/rails/generator/templates/%file_name%_generator.rb.tt diff --git a/railties/lib/rails/generators/rails/generator/templates/USAGE.tt b/railties/lib/generators/rails/generator/templates/USAGE.tt index ea9f4f12cc..ea9f4f12cc 100644 --- a/railties/lib/rails/generators/rails/generator/templates/USAGE.tt +++ b/railties/lib/generators/rails/generator/templates/USAGE.tt diff --git a/railties/lib/rails/generators/rails/generator/templates/templates/.empty_directory b/railties/lib/generators/rails/generator/templates/templates/.empty_directory index e69de29bb2..e69de29bb2 100644 --- a/railties/lib/rails/generators/rails/generator/templates/templates/.empty_directory +++ b/railties/lib/generators/rails/generator/templates/templates/.empty_directory diff --git a/railties/lib/rails/generators/rails/helper/USAGE b/railties/lib/generators/rails/helper/USAGE index 531c9b390a..531c9b390a 100644 --- a/railties/lib/rails/generators/rails/helper/USAGE +++ b/railties/lib/generators/rails/helper/USAGE diff --git a/railties/lib/rails/generators/rails/helper/helper_generator.rb b/railties/lib/generators/rails/helper/helper_generator.rb index ad66388591..ad66388591 100644 --- a/railties/lib/rails/generators/rails/helper/helper_generator.rb +++ b/railties/lib/generators/rails/helper/helper_generator.rb diff --git a/railties/lib/rails/generators/rails/helper/templates/helper.rb b/railties/lib/generators/rails/helper/templates/helper.rb index 3fe2ecdc74..3fe2ecdc74 100644 --- a/railties/lib/rails/generators/rails/helper/templates/helper.rb +++ b/railties/lib/generators/rails/helper/templates/helper.rb diff --git a/railties/lib/rails/generators/rails/integration_test/USAGE b/railties/lib/generators/rails/integration_test/USAGE index b76c35a702..b76c35a702 100644 --- a/railties/lib/rails/generators/rails/integration_test/USAGE +++ b/railties/lib/generators/rails/integration_test/USAGE diff --git a/railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb b/railties/lib/generators/rails/integration_test/integration_test_generator.rb index 363a327fcb..363a327fcb 100644 --- a/railties/lib/rails/generators/rails/integration_test/integration_test_generator.rb +++ b/railties/lib/generators/rails/integration_test/integration_test_generator.rb diff --git a/railties/lib/rails/generators/rails/mailer/USAGE b/railties/lib/generators/rails/mailer/USAGE index c56095b2c8..4b0b8ddc3b 100644 --- a/railties/lib/rails/generators/rails/mailer/USAGE +++ b/railties/lib/generators/rails/mailer/USAGE @@ -9,7 +9,7 @@ Example: `./script/generate mailer Notifications signup forgot_password invoice` creates a Notifications mailer class, views, test, and fixtures: - Mailer: app/models/notifications.rb + Mailer: app/mailers/notifications.rb Views: app/views/notifications/signup.erb [...] - Test: test/unit/test/unit/notifications_test.rb + Test: test/functional/notifications_test.rb Fixtures: test/fixtures/notifications/signup [...] diff --git a/railties/lib/rails/generators/rails/mailer/mailer_generator.rb b/railties/lib/generators/rails/mailer/mailer_generator.rb index 33f1665b83..8993181d79 100644 --- a/railties/lib/rails/generators/rails/mailer/mailer_generator.rb +++ b/railties/lib/generators/rails/mailer/mailer_generator.rb @@ -5,7 +5,7 @@ module Rails check_class_collision def create_mailer_file - template "mailer.rb", File.join('app/models', class_path, "#{file_name}.rb") + template "mailer.rb", File.join('app/mailers', class_path, "#{file_name}.rb") end hook_for :template_engine, :test_framework diff --git a/railties/lib/rails/generators/rails/mailer/templates/mailer.rb b/railties/lib/generators/rails/mailer/templates/mailer.rb index 90e0b712d6..90e0b712d6 100644 --- a/railties/lib/rails/generators/rails/mailer/templates/mailer.rb +++ b/railties/lib/generators/rails/mailer/templates/mailer.rb diff --git a/railties/lib/rails/generators/rails/metal/USAGE b/railties/lib/generators/rails/metal/USAGE index 123ec6c03f..123ec6c03f 100644 --- a/railties/lib/rails/generators/rails/metal/USAGE +++ b/railties/lib/generators/rails/metal/USAGE diff --git a/railties/lib/rails/generators/rails/metal/metal_generator.rb b/railties/lib/generators/rails/metal/metal_generator.rb index fe4f945cad..fe4f945cad 100644 --- a/railties/lib/rails/generators/rails/metal/metal_generator.rb +++ b/railties/lib/generators/rails/metal/metal_generator.rb diff --git a/railties/lib/rails/generators/rails/metal/templates/metal.rb b/railties/lib/generators/rails/metal/templates/metal.rb index e94982b69a..e94982b69a 100644 --- a/railties/lib/rails/generators/rails/metal/templates/metal.rb +++ b/railties/lib/generators/rails/metal/templates/metal.rb diff --git a/railties/lib/rails/generators/rails/migration/USAGE b/railties/lib/generators/rails/migration/USAGE index d91127aac3..d91127aac3 100644 --- a/railties/lib/rails/generators/rails/migration/USAGE +++ b/railties/lib/generators/rails/migration/USAGE diff --git a/railties/lib/rails/generators/rails/migration/migration_generator.rb b/railties/lib/generators/rails/migration/migration_generator.rb index 39fa5b63b1..39fa5b63b1 100644 --- a/railties/lib/rails/generators/rails/migration/migration_generator.rb +++ b/railties/lib/generators/rails/migration/migration_generator.rb diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/generators/rails/model/USAGE index b056d5df8b..b056d5df8b 100644 --- a/railties/lib/rails/generators/rails/model/USAGE +++ b/railties/lib/generators/rails/model/USAGE diff --git a/railties/lib/rails/generators/rails/model/model_generator.rb b/railties/lib/generators/rails/model/model_generator.rb index 629d5eed3f..629d5eed3f 100644 --- a/railties/lib/rails/generators/rails/model/model_generator.rb +++ b/railties/lib/generators/rails/model/model_generator.rb diff --git a/railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb b/railties/lib/generators/rails/model_subclass/model_subclass_generator.rb index 4649709780..99fd2f45bc 100644 --- a/railties/lib/rails/generators/rails/model_subclass/model_subclass_generator.rb +++ b/railties/lib/generators/rails/model_subclass/model_subclass_generator.rb @@ -1,5 +1,6 @@ module Rails module Generators + # TODO Deprecate me in a release > Rails 3.0 class ModelSubclassGenerator < Base desc "model_subclass is deprecated. Invoke model with --parent option instead." diff --git a/railties/lib/rails/generators/rails/observer/USAGE b/railties/lib/generators/rails/observer/USAGE index 9a20f55a89..9a20f55a89 100644 --- a/railties/lib/rails/generators/rails/observer/USAGE +++ b/railties/lib/generators/rails/observer/USAGE diff --git a/railties/lib/rails/generators/rails/observer/observer_generator.rb b/railties/lib/generators/rails/observer/observer_generator.rb index f5cedee91f..f5cedee91f 100644 --- a/railties/lib/rails/generators/rails/observer/observer_generator.rb +++ b/railties/lib/generators/rails/observer/observer_generator.rb diff --git a/railties/lib/rails/generators/rails/performance_test/USAGE b/railties/lib/generators/rails/performance_test/USAGE index ee82578cdb..ee82578cdb 100644 --- a/railties/lib/rails/generators/rails/performance_test/USAGE +++ b/railties/lib/generators/rails/performance_test/USAGE diff --git a/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb b/railties/lib/generators/rails/performance_test/performance_test_generator.rb index d1c71ab8ed..d1c71ab8ed 100644 --- a/railties/lib/rails/generators/rails/performance_test/performance_test_generator.rb +++ b/railties/lib/generators/rails/performance_test/performance_test_generator.rb diff --git a/railties/lib/rails/generators/rails/plugin/USAGE b/railties/lib/generators/rails/plugin/USAGE index 8a17fa4dec..8a17fa4dec 100644 --- a/railties/lib/rails/generators/rails/plugin/USAGE +++ b/railties/lib/generators/rails/plugin/USAGE diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/generators/rails/plugin/plugin_generator.rb index bc614bc5d3..b68b8691db 100644 --- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb +++ b/railties/lib/generators/rails/plugin/plugin_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/rails/generator/generator_generator' +require 'generators/rails/generator/generator_generator' module Rails module Generators @@ -20,15 +20,15 @@ module Rails directory 'tasks', plugin_dir('tasks') end - hook_for :generator do |instance, generator| - instance.inside instance.send(:plugin_dir), :verbose => true do - instance.invoke generator, [ instance.name ], :namespace => false + hook_for :generator do |generator| + inside plugin_dir, :verbose => true do + invoke generator, [ name ], :namespace => false end end - hook_for :test_framework do |instance, test_framework| - instance.inside instance.send(:plugin_dir), :verbose => true do - instance.invoke test_framework + hook_for :test_framework do |test_framework| + inside plugin_dir, :verbose => true do + invoke test_framework end end diff --git a/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE b/railties/lib/generators/rails/plugin/templates/MIT-LICENSE.tt index 8717df053d..8717df053d 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE +++ b/railties/lib/generators/rails/plugin/templates/MIT-LICENSE.tt diff --git a/railties/lib/rails/generators/rails/plugin/templates/README b/railties/lib/generators/rails/plugin/templates/README.tt index 702db07cb1..702db07cb1 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/README +++ b/railties/lib/generators/rails/plugin/templates/README.tt diff --git a/railties/lib/rails/generators/rails/plugin/templates/Rakefile b/railties/lib/generators/rails/plugin/templates/Rakefile.tt index 23c2245a41..23c2245a41 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/Rakefile +++ b/railties/lib/generators/rails/plugin/templates/Rakefile.tt diff --git a/railties/lib/rails/generators/rails/plugin/templates/init.rb b/railties/lib/generators/rails/plugin/templates/init.rb index 3c19a743c9..3c19a743c9 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/init.rb +++ b/railties/lib/generators/rails/plugin/templates/init.rb diff --git a/railties/lib/rails/generators/rails/plugin/templates/install.rb b/railties/lib/generators/rails/plugin/templates/install.rb index f7732d3796..f7732d3796 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/install.rb +++ b/railties/lib/generators/rails/plugin/templates/install.rb diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/%file_name%.rb.tt b/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt index d8d908a959..d8d908a959 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/lib/%file_name%.rb.tt +++ b/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt diff --git a/railties/lib/rails/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt b/railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt index 72920a9d3a..72920a9d3a 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt +++ b/railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt diff --git a/railties/lib/rails/generators/rails/plugin/templates/uninstall.rb b/railties/lib/generators/rails/plugin/templates/uninstall.rb index 9738333463..9738333463 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/uninstall.rb +++ b/railties/lib/generators/rails/plugin/templates/uninstall.rb diff --git a/railties/lib/rails/generators/rails/resource/USAGE b/railties/lib/generators/rails/resource/USAGE index 936619b0db..936619b0db 100644 --- a/railties/lib/rails/generators/rails/resource/USAGE +++ b/railties/lib/generators/rails/resource/USAGE diff --git a/railties/lib/rails/generators/rails/resource/resource_generator.rb b/railties/lib/generators/rails/resource/resource_generator.rb index a89ce7faed..43c7cc85f4 100644 --- a/railties/lib/rails/generators/rails/resource/resource_generator.rb +++ b/railties/lib/generators/rails/resource/resource_generator.rb @@ -1,5 +1,5 @@ -require 'rails/generators/rails/model/model_generator' require 'rails/generators/resource_helpers' +require 'generators/rails/model/model_generator' module Rails module Generators diff --git a/railties/lib/rails/generators/rails/scaffold/USAGE b/railties/lib/generators/rails/scaffold/USAGE index 530ccdaf0a..530ccdaf0a 100644 --- a/railties/lib/rails/generators/rails/scaffold/USAGE +++ b/railties/lib/generators/rails/scaffold/USAGE diff --git a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/generators/rails/scaffold/scaffold_generator.rb index 779f933785..fdea5bf52b 100644 --- a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb +++ b/railties/lib/generators/rails/scaffold/scaffold_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/rails/resource/resource_generator' +require 'generators/rails/resource/resource_generator' module Rails module Generators diff --git a/railties/lib/rails/generators/rails/scaffold_controller/USAGE b/railties/lib/generators/rails/scaffold_controller/USAGE index d60a3c3680..d60a3c3680 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/USAGE +++ b/railties/lib/generators/rails/scaffold_controller/USAGE diff --git a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb b/railties/lib/generators/rails/scaffold_controller/scaffold_controller_generator.rb index e544e29892..e544e29892 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +++ b/railties/lib/generators/rails/scaffold_controller/scaffold_controller_generator.rb diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/generators/rails/scaffold_controller/templates/controller.rb index 874e96a2b4..874e96a2b4 100644 --- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +++ b/railties/lib/generators/rails/scaffold_controller/templates/controller.rb diff --git a/railties/lib/rails/generators/rails/session_migration/USAGE b/railties/lib/generators/rails/session_migration/USAGE index e106f6ecc8..e106f6ecc8 100644 --- a/railties/lib/rails/generators/rails/session_migration/USAGE +++ b/railties/lib/generators/rails/session_migration/USAGE diff --git a/railties/lib/rails/generators/rails/session_migration/session_migration_generator.rb b/railties/lib/generators/rails/session_migration/session_migration_generator.rb index 258cc5b4a0..258cc5b4a0 100644 --- a/railties/lib/rails/generators/rails/session_migration/session_migration_generator.rb +++ b/railties/lib/generators/rails/session_migration/session_migration_generator.rb diff --git a/railties/lib/rails/generators/rails/stylesheets/USAGE b/railties/lib/generators/rails/stylesheets/USAGE index d6a81e51d0..d6a81e51d0 100644 --- a/railties/lib/rails/generators/rails/stylesheets/USAGE +++ b/railties/lib/generators/rails/stylesheets/USAGE diff --git a/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb b/railties/lib/generators/rails/stylesheets/stylesheets_generator.rb index ce68443c39..ce68443c39 100644 --- a/railties/lib/rails/generators/rails/stylesheets/stylesheets_generator.rb +++ b/railties/lib/generators/rails/stylesheets/stylesheets_generator.rb diff --git a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css b/railties/lib/generators/rails/stylesheets/templates/scaffold.css index d9fa2cf2dc..d9fa2cf2dc 100644 --- a/railties/lib/rails/generators/rails/stylesheets/templates/scaffold.css +++ b/railties/lib/generators/rails/stylesheets/templates/scaffold.css diff --git a/railties/lib/rails/generators/test_unit.rb b/railties/lib/generators/test_unit.rb index 62b9afaa2c..62b9afaa2c 100644 --- a/railties/lib/rails/generators/test_unit.rb +++ b/railties/lib/generators/test_unit.rb diff --git a/railties/lib/rails/generators/test_unit/controller/controller_generator.rb b/railties/lib/generators/test_unit/controller/controller_generator.rb index 39816d9990..b57a6e794f 100644 --- a/railties/lib/rails/generators/test_unit/controller/controller_generator.rb +++ b/railties/lib/generators/test_unit/controller/controller_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/test_unit' +require 'generators/test_unit' module TestUnit module Generators diff --git a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/generators/test_unit/controller/templates/functional_test.rb index 62fa5d86fd..62fa5d86fd 100644 --- a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb +++ b/railties/lib/generators/test_unit/controller/templates/functional_test.rb diff --git a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb b/railties/lib/generators/test_unit/helper/helper_generator.rb index 4ea80bf7be..9ecfaa45ab 100644 --- a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb +++ b/railties/lib/generators/test_unit/helper/helper_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/test_unit' +require 'generators/test_unit' module TestUnit module Generators diff --git a/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb b/railties/lib/generators/test_unit/helper/templates/helper_test.rb index 591e40900e..591e40900e 100644 --- a/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb +++ b/railties/lib/generators/test_unit/helper/templates/helper_test.rb diff --git a/railties/lib/rails/generators/test_unit/integration/integration_generator.rb b/railties/lib/generators/test_unit/integration/integration_generator.rb index 32d0fac029..d9d9b3bf1d 100644 --- a/railties/lib/rails/generators/test_unit/integration/integration_generator.rb +++ b/railties/lib/generators/test_unit/integration/integration_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/test_unit' +require 'generators/test_unit' module TestUnit module Generators diff --git a/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb b/railties/lib/generators/test_unit/integration/templates/integration_test.rb index 2c57158b1c..2c57158b1c 100644 --- a/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb +++ b/railties/lib/generators/test_unit/integration/templates/integration_test.rb diff --git a/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb b/railties/lib/generators/test_unit/mailer/mailer_generator.rb index 7353e5d61a..a0d73db1b0 100644 --- a/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb +++ b/railties/lib/generators/test_unit/mailer/mailer_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/test_unit' +require 'generators/test_unit' module TestUnit module Generators @@ -7,7 +7,7 @@ module TestUnit check_class_collision :suffix => "Test" def create_test_files - template "unit_test.rb", File.join('test/unit', class_path, "#{file_name}_test.rb") + template "functional_test.rb", File.join('test/functional', class_path, "#{file_name}_test.rb") end def create_fixtures_files diff --git a/railties/lib/rails/generators/test_unit/mailer/templates/fixture b/railties/lib/generators/test_unit/mailer/templates/fixture index fcce7bd805..fcce7bd805 100644 --- a/railties/lib/rails/generators/test_unit/mailer/templates/fixture +++ b/railties/lib/generators/test_unit/mailer/templates/fixture diff --git a/railties/lib/rails/generators/test_unit/mailer/templates/unit_test.rb b/railties/lib/generators/test_unit/mailer/templates/functional_test.rb index 4de94076e9..4de94076e9 100644 --- a/railties/lib/rails/generators/test_unit/mailer/templates/unit_test.rb +++ b/railties/lib/generators/test_unit/mailer/templates/functional_test.rb diff --git a/railties/lib/rails/generators/test_unit/model/model_generator.rb b/railties/lib/generators/test_unit/model/model_generator.rb index 609b815683..469306e6c5 100644 --- a/railties/lib/rails/generators/test_unit/model/model_generator.rb +++ b/railties/lib/generators/test_unit/model/model_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/test_unit' +require 'generators/test_unit' module TestUnit module Generators diff --git a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml b/railties/lib/generators/test_unit/model/templates/fixtures.yml index a30132bc99..a30132bc99 100644 --- a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml +++ b/railties/lib/generators/test_unit/model/templates/fixtures.yml diff --git a/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb b/railties/lib/generators/test_unit/model/templates/unit_test.rb index 3e0bc29d3a..3e0bc29d3a 100644 --- a/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb +++ b/railties/lib/generators/test_unit/model/templates/unit_test.rb diff --git a/railties/lib/rails/generators/test_unit/observer/observer_generator.rb b/railties/lib/generators/test_unit/observer/observer_generator.rb index 6cc1158c21..14181f4e49 100644 --- a/railties/lib/rails/generators/test_unit/observer/observer_generator.rb +++ b/railties/lib/generators/test_unit/observer/observer_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/test_unit' +require 'generators/test_unit' module TestUnit module Generators diff --git a/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb b/railties/lib/generators/test_unit/observer/templates/unit_test.rb index 03f6d5666e..03f6d5666e 100644 --- a/railties/lib/rails/generators/test_unit/observer/templates/unit_test.rb +++ b/railties/lib/generators/test_unit/observer/templates/unit_test.rb diff --git a/railties/lib/rails/generators/test_unit/performance/performance_generator.rb b/railties/lib/generators/test_unit/performance/performance_generator.rb index 99edda5461..0d9c646b26 100644 --- a/railties/lib/rails/generators/test_unit/performance/performance_generator.rb +++ b/railties/lib/generators/test_unit/performance/performance_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/test_unit' +require 'generators/test_unit' module TestUnit module Generators diff --git a/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb b/railties/lib/generators/test_unit/performance/templates/performance_test.rb index 362e3dc09f..362e3dc09f 100644 --- a/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb +++ b/railties/lib/generators/test_unit/performance/templates/performance_test.rb diff --git a/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb b/railties/lib/generators/test_unit/plugin/plugin_generator.rb index 4d65cd7d89..05adf58c4f 100644 --- a/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb +++ b/railties/lib/generators/test_unit/plugin/plugin_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/test_unit' +require 'generators/test_unit' module TestUnit module Generators diff --git a/railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt b/railties/lib/generators/test_unit/plugin/templates/%file_name%_test.rb.tt index 3e0bc29d3a..3e0bc29d3a 100644 --- a/railties/lib/rails/generators/test_unit/plugin/templates/%file_name%_test.rb.tt +++ b/railties/lib/generators/test_unit/plugin/templates/%file_name%_test.rb.tt diff --git a/railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb b/railties/lib/generators/test_unit/plugin/templates/test_helper.rb index 2ca36a1e44..2ca36a1e44 100644 --- a/railties/lib/rails/generators/test_unit/plugin/templates/test_helper.rb +++ b/railties/lib/generators/test_unit/plugin/templates/test_helper.rb diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/generators/test_unit/scaffold/scaffold_generator.rb index c0315c7fe6..a95916ae13 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +++ b/railties/lib/generators/test_unit/scaffold/scaffold_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/test_unit' +require 'generators/test_unit' require 'rails/generators/resource_helpers' module TestUnit diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/generators/test_unit/scaffold/templates/functional_test.rb index 9380aa49b6..9380aa49b6 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +++ b/railties/lib/generators/test_unit/scaffold/templates/functional_test.rb diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index 4ded2515fc..0bc7160815 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -1,9 +1,8 @@ -require "pathname" +require 'pathname' require 'active_support' require 'active_support/core_ext/kernel/reporting' require 'active_support/core_ext/logger' -require 'action_dispatch' require 'rails/initializable' require 'rails/application' @@ -18,6 +17,8 @@ require 'rails/deprecation' require 'rails/subscriber' require 'rails/ruby_version_check' +require 'action_dispatch/railtie' + # For Ruby 1.8, this initialization sets $KCODE to 'u' to enable the # multibyte safe operations. Plugin authors supporting other encodings # should override this behaviour and set the relevant +default_charset+ diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index c95316a4da..4d05f8115c 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -99,9 +99,15 @@ module Rails end end + def app + @app ||= begin + reload_routes! + middleware.build(routes) + end + end + def call(env) - @app ||= middleware.build(routes) - @app.call(env) + app.call(env) end initializer :load_application_initializers do @@ -110,6 +116,10 @@ module Rails end end + initializer :build_middleware_stack do + app + end + # Fires the user-supplied after_initialize block (Configuration#after_initialize) initializer :after_initialize do config.after_initialize_blocks.each do |block| diff --git a/railties/lib/rails/backtrace_cleaner.rb b/railties/lib/rails/backtrace_cleaner.rb index cd7dd0f80a..40198306f9 100644 --- a/railties/lib/rails/backtrace_cleaner.rb +++ b/railties/lib/rails/backtrace_cleaner.rb @@ -3,17 +3,7 @@ require 'active_support/backtrace_cleaner' module Rails class BacktraceCleaner < ActiveSupport::BacktraceCleaner ERB_METHOD_SIG = /:in `_run_erb_.*/ - - RAILS_GEMS = %w( actionpack activerecord actionmailer activesupport activeresource rails ) - - VENDOR_DIRS = %w( vendor/rails ) - SERVER_DIRS = %w( lib/mongrel bin/mongrel - lib/passenger bin/passenger-spawn-server - lib/rack ) - RAILS_NOISE = %w( script/server ) - RUBY_NOISE = %w( rubygems/custom_require benchmark.rb ) - - ALL_NOISE = VENDOR_DIRS + SERVER_DIRS + RAILS_NOISE + RUBY_NOISE + APP_DIRS = %w( app config lib test ) def initialize super @@ -22,10 +12,9 @@ module Rails add_filter { |line| line.sub('./', '/') } # for tests add_gem_filters + add_bundler_filters - add_silencer { |line| ALL_NOISE.any? { |dir| line.include?(dir) } } - add_silencer { |line| RAILS_GEMS.any? { |gem| line =~ /^#{gem} / } } - add_silencer { |line| line =~ %r(vendor/plugins/[^\/]+/lib) } + add_silencer { |line| !APP_DIRS.any? { |dir| line =~ /^#{dir}/ } } end private @@ -33,9 +22,21 @@ module Rails return unless defined? Gem (Gem.path + [Gem.default_dir]).uniq.each do |path| # http://gist.github.com/30430 - add_filter { |line| line.sub(/(#{path})\/gems\/([a-z]+)-([0-9.]+)\/(.*)/, '\2 (\3) \4')} + add_filter { |line| + line.sub(%r{(#{path})/gems/([^/]+)-([0-9.]+)/(.*)}, '\2 (\3) \4') + } end end + + def add_bundler_filters + return unless defined? Bundler + add_filter { |line| + line.sub(%r{vendor/gems/[^/]+/[^/]+/gems/([^/]+)-([0-9.]+)/(.*)}, '\1 (\2) \3') + } + add_filter { |line| + line.sub(%r{vendor/gems/[^/]+/[^/]+/dirs/([^/]+)/(.*)}, '\1 \2') + } + end end # For installing the BacktraceCleaner in the test/unit diff --git a/railties/lib/rails/bootstrap.rb b/railties/lib/rails/bootstrap.rb index b7cf70747a..5db663f9ef 100644 --- a/railties/lib/rails/bootstrap.rb +++ b/railties/lib/rails/bootstrap.rb @@ -23,8 +23,8 @@ module Rails # the load_once paths. initializer :set_autoload_paths do require 'active_support/dependencies' - ActiveSupport::Dependencies.load_paths = config.load_paths.uniq - ActiveSupport::Dependencies.load_once_paths = config.load_once_paths.uniq + ActiveSupport::Dependencies.load_paths = expand_load_path(config.load_paths) + ActiveSupport::Dependencies.load_once_paths = expand_load_path(config.load_once_paths) extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths unless extra.empty? @@ -140,7 +140,7 @@ module Rails end end - initializer :initialize_notifications do + initializer :initialize_notifications do require 'active_support/notifications' if config.colorize_logging == false @@ -152,5 +152,10 @@ module Rails Rails::Subscriber.dispatch(args) end end + + private + def expand_load_path(load_paths) + load_paths.map { |path| Dir.glob(path.to_s) }.flatten.uniq + end end end diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb index a2fab120cf..b76a7ac2d8 100644 --- a/railties/lib/rails/configuration.rb +++ b/railties/lib/rails/configuration.rb @@ -14,9 +14,12 @@ module Rails middleware.use('::Rack::Lock', :if => lambda { !ActionController::Base.allow_concurrency }) middleware.use('::Rack::Runtime') middleware.use('ActionDispatch::ShowExceptions', lambda { ActionController::Base.consider_all_requests_local }) - middleware.use('ActionDispatch::Callbacks', lambda { ActionController::Dispatcher.prepare_each_request }) + middleware.use('ActionDispatch::Notifications') + middleware.use('ActionDispatch::Callbacks', lambda { !Rails.application.config.cache_classes }) + middleware.use('ActionDispatch::Cookies') middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options }) middleware.use('ActionDispatch::Flash', :if => lambda { ActionController::Base.session_store }) + middleware.use(lambda { Rails::Rack::Metal.new(Rails.application.config.paths.app.metals.to_a, Rails.application.config.metals) }) middleware.use('ActionDispatch::ParamsParser') middleware.use('::Rack::MethodOverride') middleware.use('::ActionDispatch::Head') @@ -197,12 +200,7 @@ module Rails end def eager_load_paths - @eager_load_paths ||= %w( - app/metal - app/models - app/controllers - app/helpers - ).map { |dir| "#{root}/#{dir}" }.select { |dir| File.directory?(dir) } + @eager_load_paths ||= ["#{root}/app/*"] end def load_paths @@ -212,20 +210,13 @@ module Rails # Add the old mock paths only if the directories exists paths.concat(Dir["#{root}/test/mocks/#{Rails.env}"]) if File.exists?("#{root}/test/mocks/#{Rails.env}") - # Add the app's controller directory - paths.concat(Dir["#{root}/app/controllers/"]) - # Followed by the standard includes. paths.concat %w( app - app/metal - app/models - app/controllers - app/helpers - app/services + app/* lib vendor - ).map { |dir| "#{root}/#{dir}" }.select { |dir| File.directory?(dir) } + ).map { |dir| "#{root}/#{dir}" } paths.concat builtin_directories end diff --git a/railties/lib/rails/deprecation.rb b/railties/lib/rails/deprecation.rb index 43f08d13df..f28da5a6b0 100644 --- a/railties/lib/rails/deprecation.rb +++ b/railties/lib/rails/deprecation.rb @@ -11,7 +11,7 @@ RAILS_ROOT = (Class.new(ActiveSupport::Deprecation::DeprecationProxy) do end def warn(callstack, called, args) - msg = "RAILS_ROOT is deprecated! Use Rails.root instead." + msg = "RAILS_ROOT is deprecated! Use Rails.root instead" ActiveSupport::Deprecation.warn(msg, callstack) end end).new @@ -26,7 +26,7 @@ RAILS_ENV = (Class.new(ActiveSupport::Deprecation::DeprecationProxy) do end def warn(callstack, called, args) - msg = "RAILS_ENV is deprecated! Use Rails.env instead." + msg = "RAILS_ENV is deprecated! Use Rails.env instead" ActiveSupport::Deprecation.warn(msg, callstack) end end).new @@ -41,7 +41,7 @@ RAILS_DEFAULT_LOGGER = (Class.new(ActiveSupport::Deprecation::DeprecationProxy) end def warn(callstack, called, args) - msg = "RAILS_DEFAULT_LOGGER is deprecated! Use Rails.logger instead." + msg = "RAILS_DEFAULT_LOGGER is deprecated! Use Rails.logger instead" ActiveSupport::Deprecation.warn(msg, callstack) end end).new diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index 3713a38b33..736c36c0dc 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -87,18 +87,6 @@ module Rails @options ||= DEFAULT_OPTIONS.dup end - def self.gems_generators_paths #:nodoc: - return [] unless defined?(Gem) && Gem.respond_to?(:loaded_specs) - Gem.loaded_specs.inject([]) do |paths, (name, spec)| - paths += Dir[File.join(spec.full_gem_path, "lib/{generators,rails_generators}")] - end - end - - def self.plugins_generators_paths #:nodoc: - return [] unless defined?(Rails.root) && Rails.root - Dir[File.join(Rails.root, "vendor", "plugins", "*", "lib", "{generators,rails_generators}")] - end - # Hold configured generators fallbacks. If a plugin developer wants a # generator group to fallback to another group in case of missing generators, # they can add a fallback. @@ -126,31 +114,6 @@ module Rails @subclasses ||= [] end - # Generators load paths used on lookup. The lookup happens as: - # - # 1) lib generators - # 2) vendor/plugin generators - # 3) vendor/gems generators - # 4) ~/rails/generators - # 5) rubygems generators - # 6) builtin generators - # - # TODO Remove hardcoded paths for all, except (6). - # - def self.load_paths - @load_paths ||= begin - paths = [] - paths += Dir[File.join(Rails.root, "lib", "{generators,rails_generators}")] if defined?(Rails.root) && Rails.root - paths += Dir[File.join(Thor::Util.user_home, ".rails", "{generators,rails_generators}")] - paths += self.plugins_generators_paths - paths += self.gems_generators_paths - paths << File.expand_path(File.join(File.dirname(__FILE__), "generators")) - paths.uniq! - paths - end - end - load_paths # Cache load paths. Needed to avoid __FILE__ pointing to wrong paths. - # Rails finds namespaces similar to thor, it only adds one rule: # # Generators names must end with "_generator.rb". This is required because Rails @@ -168,34 +131,26 @@ module Rails # Rails looks for is the first and last parts of the namespace. # def self.find_by_namespace(name, base=nil, context=nil) #:nodoc: - # Mount regexps to lookup - regexps = [] - regexps << /^#{base}:[\w:]*#{name}$/ if base - regexps << /^#{name}:[\w:]*#{context}$/ if context - regexps << /^[(#{name}):]+$/ - regexps.uniq! - - # Check if generator happens to be loaded - checked = subclasses.dup - klass = find_by_regexps(regexps, checked) - return klass if klass - - # Try to require other generators by looking in load_paths - lookup(name, context) - unchecked = subclasses - checked - klass = find_by_regexps(regexps, unchecked) - return klass if klass - - # Invoke fallbacks - invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name) - end + lookups = [] + lookups << "#{base}:#{name}" if base + lookups << "#{name}:#{context}" if context + lookups << "#{name}:#{name}" unless name.to_s.include?(?:) + lookups << "#{name}" + lookups << "rails:#{name}" unless base || context || name.to_s.include?(?:) + + lookup(lookups) + + namespaces = subclasses.inject({}) do |hash, klass| + hash[klass.namespace] = klass + hash + end - # Tries to find a generator which the namespace match the regexp. - def self.find_by_regexps(regexps, klasses) - klasses.find do |klass| - namespace = klass.namespace - regexps.find { |r| namespace =~ r } + lookups.each do |namespace| + klass = namespaces[namespace] + return klass if klass end + + invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name) end # Receives a namespace, arguments and the behavior to invoke the generator. @@ -203,9 +158,8 @@ module Rails # commands. def self.invoke(namespace, args=ARGV, config={}) names = namespace.to_s.split(':') - - if klass = find_by_namespace(names.pop, names.shift || "rails") - args << "--help" if klass.arguments.any? { |a| a.required? } && args.empty? + if klass = find_by_namespace(names.pop, names.shift) + args << "--help" if args.empty? && klass.arguments.any? { |a| a.required? } klass.start(args, config) else puts "Could not find generator #{namespace}." @@ -214,26 +168,46 @@ module Rails # Show help message with available generators. def self.help - builtin = Rails::Generators.builtin.each { |n| n.sub!(/^rails:/, '') } - builtin.sort! + traverse_load_paths! + + namespaces = subclasses.map{ |k| k.namespace } + namespaces.sort! - lookup("*") - others = subclasses.map{ |k| k.namespace.gsub(':generators:', ':') } - others -= Rails::Generators.builtin - others.sort! + groups = Hash.new { |h,k| h[k] = [] } + namespaces.each do |namespace| + base = namespace.split(':').first + groups[base] << namespace + end - puts "Please select a generator." - puts "Builtin: #{builtin.join(', ')}." - puts "Others: #{others.join(', ')}." unless others.empty? + puts "Usage:" + puts " script/generate GENERATOR [args] [options]" + puts + puts "General options:" + puts " -h, [--help] # Print generators options and usage" + puts " -p, [--pretend] # Run but do not make any changes" + puts " -f, [--force] # Overwrite files that already exist" + puts " -s, [--skip] # Skip files that already exist" + puts " -q, [--quiet] # Supress status output" + puts + puts "Please choose a generator below." + puts + + # Print Rails defaults first. + rails = groups.delete("rails") + rails.map! { |n| n.sub(/^rails:/, '') } + print_list("rails", rails) + + groups.sort.each { |b, n| print_list(b, n) } end protected - # Keep builtin generators in an Array. - def self.builtin #:nodoc: - Dir[File.dirname(__FILE__) + '/generators/*/*'].collect do |file| - file.split('/')[-2, 2].join(':') - end + # Prints a list of generators. + def self.print_list(base, namespaces) #:nodoc: + return if namespaces.empty? + puts "#{base.camelize}:" + namespaces.each { |namespace| puts(" #{namespace}") } + puts end # Try fallbacks for the given base. @@ -252,27 +226,55 @@ module Rails nil end + # This will try to load any generator in the load path to show in help. + def self.traverse_load_paths! #:nodoc: + $LOAD_PATH.each do |base| + Dir[File.join(base, "{generators,rails_generators}", "**", "*_generator.rb")].each do |path| + begin + require path + rescue Exception => e + # No problem + end + end + end + end + # Receives namespaces in an array and tries to find matching generators # in the load path. - def self.lookup(*attempts) #:nodoc: - attempts.compact! - attempts.uniq! - attempts = "{#{attempts.join(',')}}_generator.rb" + def self.lookup(namespaces) #:nodoc: + paths = namespaces_to_paths(namespaces) + + paths.each do |path| + ["generators", "rails_generators"].each do |base| + path = "#{base}/#{path}_generator" - self.load_paths.each do |path| - Dir[File.join(path, '**', attempts)].each do |file| begin - require file + require path + return + rescue LoadError => e + raise unless e.message =~ /#{Regexp.escape(path)}$/ rescue NameError => e - raise unless e.message =~ /Rails::Generator/ - warn "[WARNING] Could not load generator at #{file.inspect} because it's a Rails 2.x generator, which is not supported anymore" - rescue Exception => e - warn "[WARNING] Could not load generator at #{file.inspect}. Error: #{e.message}" + raise unless e.message =~ /Rails::Generator([\s(::)]|$)/ + warn "[WARNING] Could not load generator #{path.inspect} because it's a Rails 2.x generator, which is not supported anymore. Error: #{e.message}" end end end end + # Convert namespaces to paths by replacing ":" for "/" and adding + # an extra lookup. For example, "rails:model" should be searched + # in both: "rails/model/model_generator" and "rails/model_generator". + def self.namespaces_to_paths(namespaces) #:nodoc: + paths = [] + namespaces.each do |namespace| + pieces = namespace.split(":") + paths << pieces.dup.push(pieces.last).join("/") + paths << pieces.join("/") + end + paths.uniq! + paths + end + end end diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb index 26abb46644..f4b2bd1ae9 100644 --- a/railties/lib/rails/generators/base.rb +++ b/railties/lib/rails/generators/base.rb @@ -17,7 +17,7 @@ module Rails def self.source_root @_rails_source_root ||= begin if base_name && generator_name - File.expand_path(File.join(File.dirname(__FILE__), base_name, generator_name, 'templates')) + File.expand_path(File.join("../../generators", base_name, generator_name, 'templates'), File.dirname(__FILE__)) end end end @@ -42,7 +42,7 @@ module Rails # def self.namespace(name=nil) return super if name - @namespace ||= super.sub(/_generator$/, '') + @namespace ||= super.sub(/_generator$/, '').sub(/:generators:/, ':') end # Invoke a generator based on the value supplied by the user to the @@ -324,9 +324,13 @@ module Rails # added hook is being used. # def self.prepare_for_invocation(name, value) #:nodoc: + return super unless value.is_a?(String) || value.is_a?(Symbol) + if value && constants = self.hooks[name] value = name if TrueClass === value Rails::Generators.find_by_namespace(value, *constants) + elsif klass = Rails::Generators.find_by_namespace(value) + klass else super end diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index 1d4f52286e..3e851bf888 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -6,10 +6,12 @@ module Rails class NamedBase < Base argument :name, :type => :string - attr_reader :class_name, :singular_name, :plural_name, :table_name, - :class_path, :file_path, :class_nesting_depth + no_tasks { + attr_reader :class_name, :singular_name, :plural_name, :table_name, + :class_path, :file_path, :class_nesting_depth - alias :file_name :singular_name + alias :file_name :singular_name + } def initialize(args, *options) #:nodoc: # Unfreeze name in case it's given as a frozen string diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb index 99954e2292..7e00a222ed 100644 --- a/railties/lib/rails/generators/resource_helpers.rb +++ b/railties/lib/rails/generators/resource_helpers.rb @@ -9,10 +9,14 @@ module Rails mattr_accessor :skip_warn def self.included(base) #:nodoc: - base.send :attr_reader, :controller_name, :controller_class_name, :controller_file_name, - :controller_class_path, :controller_file_path + base.class_eval do + class_option :force_plural, :type => :boolean, :desc => "Forces the use of a plural ModelName" - base.send :class_option, :force_plural, :type => :boolean, :desc => "Forces the use of a plural ModelName" + no_tasks { + attr_reader :controller_name, :controller_class_name, :controller_file_name, + :controller_class_path, :controller_file_path + } + end end # Set controller variables on initialization. diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb index a057b8f701..0c09730963 100644 --- a/railties/lib/rails/plugin.rb +++ b/railties/lib/rails/plugin.rb @@ -50,7 +50,11 @@ module Rails end initializer :add_view_paths, :after => :initialize_framework_views do - ActionController::Base.view_paths.concat ["#{path}/app/views"] if File.directory?("#{path}/app/views") + plugin_views = "#{path}/app/views" + if File.directory?(plugin_views) + ActionController::Base.view_paths.concat([plugin_views]) if defined? ActionController + ActionMailer::Base.view_paths.concat([plugin_views]) if defined? ActionMailer + end end # TODO Isn't it supposed to be :after => "action_controller.initialize_routing" ? @@ -62,4 +66,4 @@ module Rails end end end -end
\ No newline at end of file +end diff --git a/railties/lib/rails/rack.rb b/railties/lib/rails/rack.rb index d487bd0542..36945a6b0f 100644 --- a/railties/lib/rails/rack.rb +++ b/railties/lib/rails/rack.rb @@ -1,7 +1,8 @@ module Rails module Rack - autoload :Debugger, "rails/rack/debugger" + autoload :Debugger, "rails/rack/debugger" autoload :LogTailer, "rails/rack/log_tailer" - autoload :Static, "rails/rack/static" + autoload :Metal, "rails/rack/metal" + autoload :Static, "rails/rack/static" end end diff --git a/railties/lib/rails/rack/metal.rb b/railties/lib/rails/rack/metal.rb new file mode 100644 index 0000000000..565f95d7c4 --- /dev/null +++ b/railties/lib/rails/rack/metal.rb @@ -0,0 +1,26 @@ +require 'action_dispatch' + +module Rails + module Rack + class Metal + def initialize(metal_roots, metals=nil) + load_list = metals || Dir["{#{metal_roots.join(",")}}/**/*.rb"] + + @metals = load_list.map { |metal| + metal = File.basename(metal, '.rb') + require_dependency metal + metal.camelize.constantize + }.compact + end + + def new(app) + ActionDispatch::Cascade.new(@metals, app) + end + + def name + ActionDispatch::Cascade.name + end + alias_method :to_s, :name + end + end +end diff --git a/railties/lib/rails/subscriber.rb b/railties/lib/rails/subscriber.rb index 11102522b0..db92916043 100644 --- a/railties/lib/rails/subscriber.rb +++ b/railties/lib/rails/subscriber.rb @@ -66,7 +66,7 @@ module Rails subscriber.send(name, ActiveSupport::Notifications::Event.new(*args)) end - if args[0] == "action_dispatch.callback" && !subscribers.empty? + if args[0] == "action_dispatch.after_dispatch" && !subscribers.empty? flush_all! log_tailer.tail! if log_tailer end diff --git a/railties/lib/rails/tasks/documentation.rake b/railties/lib/rails/tasks/documentation.rake index db1939c45f..65d0d476ba 100644 --- a/railties/lib/rails/tasks/documentation.rake +++ b/railties/lib/rails/tasks/documentation.rake @@ -55,7 +55,7 @@ namespace :doc do desc "Generate Rails guides" task :guides do require File.join(RAILTIES_PATH, "guides/rails_guides") - RailsGuides::Generator.new(File.join(RAILS_ROOT, "doc/guides")).generate + RailsGuides::Generator.new(Rails.root.join("doc/guides")).generate end namespace :plugins do diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake index f7b53885c8..5d7c094d8b 100644 --- a/railties/lib/rails/tasks/framework.rake +++ b/railties/lib/rails/tasks/framework.rake @@ -85,15 +85,16 @@ namespace :rails do template = ENV["LOCATION"] template = File.expand_path(template) if template !~ %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} - require 'generators' - generator = Rails::Generators::App.new [ Rails.root ], {}, :destination_root => Rails.root + require 'rails/generators' + require 'generators/rails/app/app_generator' + generator = Rails::Generators::AppGenerator.new [ Rails.root ], {}, :destination_root => Rails.root generator.apply template, :verbose => false end namespace :update do def invoke_from_app_generator(method) require 'rails/generators' - require 'rails/generators/rails/app/app_generator' + require 'generators/rails/app/app_generator' generator = Rails::Generators::AppGenerator.new ["rails"], { :with_dispatchers => true }, :destination_root => Rails.root diff --git a/railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb index a585b37b73..eda3b52c4f 100644 --- a/railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb +++ b/railties/lib/rails/vendor/thor-0.12.3/lib/thor/group.rb @@ -252,10 +252,13 @@ class Thor::Group shell.padding += 1 result = if block_given? - if block.arity == 2 - block.call(self, klass) - else + case block.arity + when 3 block.call(self, klass, task) + when 2 + block.call(self, klass) + when 1 + instance_exec(klass, &block) end else invoke klass, task, *args diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index 7b3077bb6e..1c5cc62ecd 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -18,7 +18,9 @@ module ApplicationTests "Rack::Lock", "Rack::Runtime", "ActionDispatch::ShowExceptions", + "ActionDispatch::Notifications", "ActionDispatch::Callbacks", + "ActionDispatch::Cookies", "ActionDispatch::Session::CookieStore", "ActionDispatch::Flash", "ActionDispatch::Cascade", diff --git a/railties/test/application/notifications_test.rb b/railties/test/application/notifications_test.rb index 1eb0777db8..db8605edbe 100644 --- a/railties/test/application/notifications_test.rb +++ b/railties/test/application/notifications_test.rb @@ -64,7 +64,7 @@ module ApplicationTests ActiveRecord::Base.logger = logger = MockLogger.new - # Mimic an ActiveRecord notifications + # Mimic ActiveRecord notifications instrument "active_record.sql", :name => "SQL", :sql => "SHOW tables" wait diff --git a/railties/test/backtrace_cleaner_test.rb b/railties/test/backtrace_cleaner_test.rb index 6cff591b94..80077378db 100644 --- a/railties/test/backtrace_cleaner_test.rb +++ b/railties/test/backtrace_cleaner_test.rb @@ -37,7 +37,7 @@ if defined? Gem test "should format installed gems correctly" do @backtrace = [ "#{Gem.path[0]}/gems/nosuchgem-1.2.3/lib/foo.rb" ] - @result = @cleaner.clean(@backtrace) + @result = @cleaner.clean(@backtrace, :all) assert_equal "nosuchgem (1.2.3) lib/foo.rb", @result[0] end @@ -46,7 +46,7 @@ if defined? Gem # skip this test if default_dir is the only directory on Gem.path if @target_dir @backtrace = [ "#{@target_dir}/gems/nosuchgem-1.2.3/lib/foo.rb" ] - @result = @cleaner.clean(@backtrace) + @result = @cleaner.clean(@backtrace, :all) assert_equal "nosuchgem (1.2.3) lib/foo.rb", @result[0] end end diff --git a/railties/test/fixtures/lib/generators/active_record/fixjour/fixjour_generator.rb b/railties/test/fixtures/lib/generators/active_record/fixjour_generator.rb index a7d079a1bc..7a4edb8bcb 100644 --- a/railties/test/fixtures/lib/generators/active_record/fixjour/fixjour_generator.rb +++ b/railties/test/fixtures/lib/generators/active_record/fixjour_generator.rb @@ -1,4 +1,4 @@ -require 'rails/generators/active_record' +require 'generators/active_record' module ActiveRecord module Generators diff --git a/railties/test/fixtures/lib/generators/rails/javascripts_generator.rb b/railties/test/fixtures/lib/generators/rails/javascripts_generator.rb deleted file mode 100644 index cad5e96784..0000000000 --- a/railties/test/fixtures/lib/generators/rails/javascripts_generator.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Rails::Generators - class JavascriptsGenerator < Rails::Generators::NamedBase - end -end diff --git a/railties/test/fixtures/vendor/gems/gems/wrong/lib/generators/wrong_generator.rb b/railties/test/fixtures/lib/generators/wrong_generator.rb index 6aa7cb052e..6aa7cb052e 100644 --- a/railties/test/fixtures/vendor/gems/gems/wrong/lib/generators/wrong_generator.rb +++ b/railties/test/fixtures/lib/generators/wrong_generator.rb diff --git a/railties/test/fixtures/vendor/another_gem_path/xspec/lib/generators/xspec_generator.rb b/railties/test/fixtures/vendor/another_gem_path/xspec/lib/generators/xspec_generator.rb deleted file mode 100644 index cd477eb4c9..0000000000 --- a/railties/test/fixtures/vendor/another_gem_path/xspec/lib/generators/xspec_generator.rb +++ /dev/null @@ -1,2 +0,0 @@ -class XspecGenerator < Rails::Generators::NamedBase -end diff --git a/railties/test/fixtures/vendor/plugins/mspec/lib/rails_generators/mspec_generator.rb b/railties/test/fixtures/vendor/plugins/mspec/lib/rails_generators/mspec_generator.rb deleted file mode 100644 index 191bdbf2fc..0000000000 --- a/railties/test/fixtures/vendor/plugins/mspec/lib/rails_generators/mspec_generator.rb +++ /dev/null @@ -1,2 +0,0 @@ -class MspecGenerator < Rails::Generators::NamedBase -end diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 27b6a49566..cb1fa96e0d 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -1,7 +1,11 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/app/app_generator' +require 'generators/rails/app/app_generator' -class ActionsTest < GeneratorsTestCase +# TODO This line shouldn't be required +require 'generators/rails/model/model_generator' + +class ActionsTest < Rails::Generators::TestCase + include GeneratorsTestHelper tests Rails::Generators::AppGenerator arguments [destination_root] @@ -11,6 +15,16 @@ class ActionsTest < GeneratorsTestCase @svn_plugin_uri = 'svn://svnhub.com/technoweenie/restful-authentication/trunk' end + def test_invoke_other_generator_with_shortcut + action :invoke, 'model', ['my_model'] + assert_file 'app/models/my_model.rb', /MyModel/ + end + + def test_invoke_other_generator_with_full_namespace + action :invoke, 'rails:model', ['my_model'] + assert_file 'app/models/my_model.rb', /MyModel/ + end + def test_create_file_should_write_data_to_file_path action :create_file, 'lib/test_file.rb', 'heres test data' assert_file 'lib/test_file.rb', 'heres test data' diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 62ea07f14e..f821f5caf3 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -1,8 +1,9 @@ require 'abstract_unit' require 'generators/generators_test_helper' -require 'rails/generators/rails/app/app_generator' +require 'generators/rails/app/app_generator' -class AppGeneratorTest < GeneratorsTestCase +class AppGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments [destination_root] def setup @@ -80,11 +81,10 @@ class AppGeneratorTest < GeneratorsTestCase assert_no_file "config/database.yml" end - # TODO: Bring this back using requires - # def test_activerecord_is_removed_from_frameworks_if_skip_activerecord_is_given - # run_generator ["--skip-activerecord"] - # assert_file "config/application.rb", /config\.frameworks \-= \[ :active_record \]/ - # end + def test_activerecord_is_removed_from_frameworks_if_skip_activerecord_is_given + run_generator [destination_root, "--skip-activerecord"] + assert_file "config/boot.rb", /# require "active_record\/railtie"/ + end def test_prototype_and_test_unit_are_added_by_default run_generator @@ -159,7 +159,7 @@ class AppGeneratorTest < GeneratorsTestCase end def test_default_namespace - assert_match "rails:generators:app", Rails::Generators::AppGenerator.namespace + assert_match "rails:app", Rails::Generators::AppGenerator.namespace end def test_file_is_added_for_backwards_compatibility diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb index 8e2fd3b9ed..79a4e5bf17 100644 --- a/railties/test/generators/controller_generator_test.rb +++ b/railties/test/generators/controller_generator_test.rb @@ -1,7 +1,8 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/controller/controller_generator' +require 'generators/rails/controller/controller_generator' -class ControllerGeneratorTest < GeneratorsTestCase +class ControllerGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(Account foo bar) def test_help_does_not_show_invoked_generators_options_if_they_already_exist diff --git a/railties/test/generators/generator_generator_test.rb b/railties/test/generators/generator_generator_test.rb index 28377f23b0..f3fd688e4f 100644 --- a/railties/test/generators/generator_generator_test.rb +++ b/railties/test/generators/generator_generator_test.rb @@ -1,7 +1,8 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/generator/generator_generator' +require 'generators/rails/generator/generator_generator' -class GeneratorGeneratorTest < GeneratorsTestCase +class GeneratorGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(awesome) def test_generator_skeleton_is_created diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb index 54953b76c8..3cd16a69f9 100644 --- a/railties/test/generators/generators_test_helper.rb +++ b/railties/test/generators/generators_test_helper.rb @@ -10,21 +10,19 @@ Rails.application.config.root = Rails.root require 'rails/generators' require 'rails/generators/test_case' -require 'rubygems' require 'active_record' require 'action_dispatch' -class GeneratorsTestCase < Rails::Generators::TestCase - destination File.join(Rails.root, "tmp") - setup :prepare_destination +module GeneratorsTestHelper + def self.included(base) + base.class_eval do + destination File.join(Rails.root, "tmp") + setup :prepare_destination - def self.inherited(base) - base.tests Rails::Generators.const_get(base.name.sub(/Test$/, '')) - rescue - # Do nothing. - end - - def test_truth - # Don't cry test/unit + begin + base.tests Rails::Generators.const_get(base.name.sub(/Test$/, '')) + rescue + end + end end end
\ No newline at end of file diff --git a/railties/test/generators/helper_generator_test.rb b/railties/test/generators/helper_generator_test.rb index cf18782986..6d7168738e 100644 --- a/railties/test/generators/helper_generator_test.rb +++ b/railties/test/generators/helper_generator_test.rb @@ -1,10 +1,11 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/helper/helper_generator' +require 'generators/rails/helper/helper_generator' ObjectHelper = Class.new AnotherObjectHelperTest = Class.new -class HelperGeneratorTest < GeneratorsTestCase +class HelperGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(admin) def test_helper_skeleton_is_created diff --git a/railties/test/generators/integration_test_generator_test.rb b/railties/test/generators/integration_test_generator_test.rb index 88e18be5b2..d7fc324c88 100644 --- a/railties/test/generators/integration_test_generator_test.rb +++ b/railties/test/generators/integration_test_generator_test.rb @@ -1,7 +1,8 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/integration_test/integration_test_generator' +require 'generators/rails/integration_test/integration_test_generator' -class IntegrationTestGeneratorTest < GeneratorsTestCase +class IntegrationTestGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(integration) def test_integration_test_skeleton_is_created diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb index ee4346eb71..dfc3130f77 100644 --- a/railties/test/generators/mailer_generator_test.rb +++ b/railties/test/generators/mailer_generator_test.rb @@ -1,12 +1,13 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/mailer/mailer_generator' +require 'generators/rails/mailer/mailer_generator' -class MailerGeneratorTest < GeneratorsTestCase +class MailerGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(notifier foo bar) def test_mailer_skeleton_is_created run_generator - assert_file "app/models/notifier.rb", /class Notifier < ActionMailer::Base/ + assert_file "app/mailers/notifier.rb", /class Notifier < ActionMailer::Base/ end def test_check_class_collision @@ -16,7 +17,7 @@ class MailerGeneratorTest < GeneratorsTestCase def test_invokes_default_test_framework run_generator - assert_file "test/unit/notifier_test.rb", /class NotifierTest < ActionMailer::TestCase/ + assert_file "test/functional/notifier_test.rb", /class NotifierTest < ActionMailer::TestCase/ assert_file "test/fixtures/notifier/foo", /app\/views\/notifier\/foo/ assert_file "test/fixtures/notifier/bar", /app\/views\/notifier\/bar/ end @@ -39,7 +40,7 @@ class MailerGeneratorTest < GeneratorsTestCase def test_actions_are_turned_into_methods run_generator - assert_file "app/models/notifier.rb", /def foo/ - assert_file "app/models/notifier.rb", /def bar/ + assert_file "app/mailers/notifier.rb", /def foo/ + assert_file "app/mailers/notifier.rb", /def bar/ end end diff --git a/railties/test/generators/metal_generator_test.rb b/railties/test/generators/metal_generator_test.rb index 5d6a277561..e3a2384885 100644 --- a/railties/test/generators/metal_generator_test.rb +++ b/railties/test/generators/metal_generator_test.rb @@ -1,7 +1,8 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/metal/metal_generator' +require 'generators/rails/metal/metal_generator' -class MetalGeneratorTest < GeneratorsTestCase +class MetalGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(foo) def test_metal_skeleton_is_created diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb index 2fd3e5c056..811a712fd5 100644 --- a/railties/test/generators/migration_generator_test.rb +++ b/railties/test/generators/migration_generator_test.rb @@ -1,7 +1,9 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/migration/migration_generator' +require 'generators/rails/migration/migration_generator' + +class MigrationGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper -class MigrationGeneratorTest < GeneratorsTestCase def test_migration migration = "change_title_body_from_posts" run_generator [migration] diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index 051a43706b..79ce9a2a7b 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -1,7 +1,8 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/model/model_generator' +require 'generators/rails/model/model_generator' -class ModelGeneratorTest < GeneratorsTestCase +class ModelGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(Account name:string age:integer) def test_help_shows_invoked_generators_options diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb index 8c1df3b992..99eb431a49 100644 --- a/railties/test/generators/named_base_test.rb +++ b/railties/test/generators/named_base_test.rb @@ -1,5 +1,5 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator' +require 'generators/rails/scaffold_controller/scaffold_controller_generator' # Mock out what we need from AR::Base. module ActiveRecord @@ -11,7 +11,8 @@ module ActiveRecord end end -class NamedBaseTest < GeneratorsTestCase +class NamedBaseTest < Rails::Generators::TestCase + include GeneratorsTestHelper tests Rails::Generators::ScaffoldControllerGenerator def test_named_generator_attributes diff --git a/railties/test/generators/observer_generator_test.rb b/railties/test/generators/observer_generator_test.rb index 44d9e4a9f3..058a19228d 100644 --- a/railties/test/generators/observer_generator_test.rb +++ b/railties/test/generators/observer_generator_test.rb @@ -1,7 +1,8 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/observer/observer_generator' +require 'generators/rails/observer/observer_generator' -class ObserverGeneratorTest < GeneratorsTestCase +class ObserverGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(account) def test_invokes_default_orm diff --git a/railties/test/generators/performance_test_generator_test.rb b/railties/test/generators/performance_test_generator_test.rb index 099575ea1d..c95063a127 100644 --- a/railties/test/generators/performance_test_generator_test.rb +++ b/railties/test/generators/performance_test_generator_test.rb @@ -1,7 +1,8 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/performance_test/performance_test_generator' +require 'generators/rails/performance_test/performance_test_generator' -class PerformanceTestGeneratorTest < GeneratorsTestCase +class PerformanceTestGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(performance) def test_performance_test_skeleton_is_created diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index f84b8b6d50..4bfe210efb 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -1,17 +1,33 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/plugin/plugin_generator' +require 'generators/rails/plugin/plugin_generator' -class PluginGeneratorTest < GeneratorsTestCase +class PluginGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(plugin_fu) def test_plugin_skeleton_is_created run_generator + year = Date.today.year %w( vendor/plugins vendor/plugins/plugin_fu + vendor/plugins/plugin_fu/init.rb + vendor/plugins/plugin_fu/install.rb + vendor/plugins/plugin_fu/uninstall.rb vendor/plugins/plugin_fu/lib + vendor/plugins/plugin_fu/lib/plugin_fu.rb ).each{ |path| assert_file path } + + %w( + vendor/plugins/plugin_fu/README + vendor/plugins/plugin_fu/Rakefile + ).each{ |path| assert_file path, /PluginFu/ } + + %w( + vendor/plugins/plugin_fu/README + vendor/plugins/plugin_fu/MIT-LICENSE + ).each{ |path| assert_file path, /#{year}/ } end def test_check_class_collision diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb index 15c0ca0f01..959934bd71 100644 --- a/railties/test/generators/resource_generator_test.rb +++ b/railties/test/generators/resource_generator_test.rb @@ -1,7 +1,8 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/resource/resource_generator' +require 'generators/rails/resource/resource_generator' -class ResourceGeneratorTest < GeneratorsTestCase +class ResourceGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(account) def setup diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 7593c14dd9..f971598d18 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -1,12 +1,13 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator' +require 'generators/rails/scaffold_controller/scaffold_controller_generator' module Unknown module Generators end end -class ScaffoldControllerGeneratorTest < GeneratorsTestCase +class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(User name:string age:integer) def test_controller_skeleton_is_created diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 4ddc7b1c89..a7e9c8a231 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -1,7 +1,8 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/scaffold/scaffold_generator' +require 'generators/rails/scaffold/scaffold_generator' -class ScaffoldGeneratorTest < GeneratorsTestCase +class ScaffoldGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper arguments %w(product_line title:string price:integer) def setup diff --git a/railties/test/generators/session_migration_generator_test.rb b/railties/test/generators/session_migration_generator_test.rb index 251ffb19ed..de28b4c75b 100644 --- a/railties/test/generators/session_migration_generator_test.rb +++ b/railties/test/generators/session_migration_generator_test.rb @@ -1,7 +1,9 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/session_migration/session_migration_generator' +require 'generators/rails/session_migration/session_migration_generator' + +class SessionMigrationGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper -class SessionMigrationGeneratorTest < GeneratorsTestCase def test_session_migration_with_default_name run_generator assert_migration "db/migrate/add_sessions_table.rb", /class AddSessionsTable < ActiveRecord::Migration/ diff --git a/railties/test/generators/stylesheets_generator_test.rb b/railties/test/generators/stylesheets_generator_test.rb index d9079327ba..718fcb1fa7 100644 --- a/railties/test/generators/stylesheets_generator_test.rb +++ b/railties/test/generators/stylesheets_generator_test.rb @@ -1,7 +1,9 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/stylesheets/stylesheets_generator' +require 'generators/rails/stylesheets/stylesheets_generator' + +class StylesheetsGeneratorTest < Rails::Generators::TestCase + include GeneratorsTestHelper -class StylesheetsGeneratorTest < GeneratorsTestCase def test_copy_stylesheets run_generator assert_file "public/stylesheets/scaffold.css" diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb index 2df218debc..60c81a813f 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -1,15 +1,21 @@ require 'generators/generators_test_helper' -require 'rails/generators/rails/model/model_generator' -require 'rails/generators/test_unit/model/model_generator' +require 'generators/rails/model/model_generator' +require 'generators/test_unit/model/model_generator' require 'mocha' -class GeneratorsTest < GeneratorsTestCase +class GeneratorsTest < Rails::Generators::TestCase + include GeneratorsTestHelper + def setup - Rails::Generators.instance_variable_set(:@load_paths, nil) - Gem.stubs(:respond_to?).with(:loaded_specs).returns(false) + @path = File.expand_path("lib", Rails.root) + $LOAD_PATH.unshift(@path) + end + + def teardown + $LOAD_PATH.delete(@path) end - def test_invoke_add_generators_to_raw_lookups + def test_simple_invoke TestUnit::Generators::ModelGenerator.expects(:start).with(["Account"], {}) Rails::Generators.invoke("test_unit:model", ["Account"]) end @@ -34,87 +40,66 @@ class GeneratorsTest < GeneratorsTestCase Rails::Generators.invoke :model, ["Account"], :behavior => :skip end - def test_find_by_namespace_without_base_or_context - assert_nil Rails::Generators.find_by_namespace(:model) + def test_find_by_namespace + klass = Rails::Generators.find_by_namespace("rails:model") + assert klass + assert_equal "rails:model", klass.namespace end def test_find_by_namespace_with_base klass = Rails::Generators.find_by_namespace(:model, :rails) assert klass - assert_equal "rails:generators:model", klass.namespace + assert_equal "rails:model", klass.namespace end def test_find_by_namespace_with_context klass = Rails::Generators.find_by_namespace(:test_unit, nil, :model) assert klass - assert_equal "test_unit:generators:model", klass.namespace - end - - def test_find_by_namespace_with_duplicated_name - klass = Rails::Generators.find_by_namespace(:foobar) - assert klass - assert_equal "foobar:foobar", klass.namespace + assert_equal "test_unit:model", klass.namespace end - def test_find_by_namespace_lookup_to_the_rails_root_folder + def test_find_by_namespace_with_generator_on_root klass = Rails::Generators.find_by_namespace(:fixjour) assert klass assert_equal "fixjour", klass.namespace end - def test_find_by_namespace_lookup_to_deep_rails_root_folders + def test_find_by_namespace_in_subfolder klass = Rails::Generators.find_by_namespace(:fixjour, :active_record) assert klass - assert_equal "active_record:generators:fixjour", klass.namespace + assert_equal "active_record:fixjour", klass.namespace end - def test_find_by_namespace_lookup_traverse_folders - klass = Rails::Generators.find_by_namespace(:javascripts, :rails) + def test_find_by_namespace_with_duplicated_name + klass = Rails::Generators.find_by_namespace(:foobar) assert klass - assert_equal "rails:generators:javascripts", klass.namespace + assert_equal "foobar:foobar", klass.namespace end - def test_find_by_namespace_lookup_to_vendor_folders - klass = Rails::Generators.find_by_namespace(:mspec) - assert klass - assert_equal "mspec", klass.namespace + def test_find_by_namespace_without_base_or_context_looks_into_rails_namespace + assert Rails::Generators.find_by_namespace(:model) end - def test_find_by_namespace_lookup_with_gem_specification - assert_nil Rails::Generators.find_by_namespace(:xspec) - Rails::Generators.instance_variable_set(:@load_paths, nil) - - spec = Gem::Specification.new - spec.expects(:full_gem_path).returns(File.join(Rails.root, 'vendor', 'another_gem_path', 'xspec')) - Gem.expects(:respond_to?).with(:loaded_specs).returns(true) - Gem.expects(:loaded_specs).returns(:spec => spec) - - klass = Rails::Generators.find_by_namespace(:xspec) - assert klass - assert_equal "xspec", klass.namespace - end - - def test_builtin_generators - assert Rails::Generators.builtin.include?("rails:model") + def test_find_by_namespace_show_warning_if_generator_cant_be_loaded + output = capture(:stderr) { Rails::Generators.find_by_namespace(:wrong) } + assert_match /\[WARNING\] Could not load generator/, output + assert_match /Rails 2\.x generator/, output end def test_rails_generators_help_with_builtin_information output = capture(:stdout){ Rails::Generators.help } - assert_match /model/, output - assert_match /scaffold_controller/, output + assert_match /Rails:/, output + assert_match /^ model$/, output + assert_match /^ scaffold_controller$/, output end def test_rails_generators_with_others_information - output = capture(:stdout){ Rails::Generators.help }.split("\n").last - assert_equal "Others: active_record:fixjour, fixjour, foobar:foobar, mspec, rails:javascripts, xspec.", output - end - - def test_warning_is_shown_if_generator_cant_be_loaded - Rails::Generators.load_paths << File.join(Rails.root, "vendor", "gems", "gems", "wrong") - output = capture(:stderr){ Rails::Generators.find_by_namespace(:wrong) } - - assert_match /\[WARNING\] Could not load generator at/, output - assert_match /Rails 2\.x generator/, output + output = capture(:stdout){ Rails::Generators.help } + assert_match /ActiveRecord:/, output + assert_match /Fixjour:/, output + assert_match /^ active_record:model$/, output + assert_match /^ active_record:fixjour$/, output + assert_match /^ fixjour$/, output end def test_no_color_sets_proper_shell @@ -124,36 +109,18 @@ class GeneratorsTest < GeneratorsTestCase Thor::Base.shell = Thor::Shell::Color end - def test_rails_root_templates - template = File.join(Rails.root, "lib", "templates", "active_record", "model", "model.rb") - - # Create template - mkdir_p(File.dirname(template)) - File.open(template, 'w'){ |f| f.write "empty" } - - output = capture(:stdout) do - Rails::Generators.invoke :model, ["user"], :destination_root => destination_root - end - - assert_file "app/models/user.rb" do |content| - assert_equal "empty", content - end - ensure - rm_rf File.dirname(template) - end - def test_fallbacks_for_generators_on_find_by_namespace Rails::Generators.fallbacks[:remarkable] = :test_unit klass = Rails::Generators.find_by_namespace(:plugin, :remarkable) assert klass - assert_equal "test_unit:generators:plugin", klass.namespace + assert_equal "test_unit:plugin", klass.namespace end def test_fallbacks_for_generators_on_find_by_namespace_with_context Rails::Generators.fallbacks[:remarkable] = :test_unit klass = Rails::Generators.find_by_namespace(:remarkable, :rails, :plugin) assert klass - assert_equal "test_unit:generators:plugin", klass.namespace + assert_equal "test_unit:plugin", klass.namespace end def test_fallbacks_for_generators_on_invoke @@ -181,8 +148,26 @@ class GeneratorsTest < GeneratorsTestCase Rails::Generators.subclasses.delete(klass) end + def test_rails_root_templates + template = File.join(Rails.root, "lib", "templates", "active_record", "model", "model.rb") + + # Create template + mkdir_p(File.dirname(template)) + File.open(template, 'w'){ |f| f.write "empty" } + + output = capture(:stdout) do + Rails::Generators.invoke :model, ["user"], :destination_root => destination_root + end + + assert_file "app/models/user.rb" do |content| + assert_equal "empty", content + end + ensure + rm_rf File.dirname(template) + end + def test_source_paths_for_not_namespaced_generators - mspec = Rails::Generators.find_by_namespace :mspec - assert mspec.source_paths.include?(File.join(Rails.root, "lib", "templates", "mspec")) + mspec = Rails::Generators.find_by_namespace :fixjour + assert mspec.source_paths.include?(File.join(Rails.root, "lib", "templates", "fixjour")) end end diff --git a/railties/test/subscriber_test.rb b/railties/test/subscriber_test.rb index ac34939510..fa3f7bfabb 100644 --- a/railties/test/subscriber_test.rb +++ b/railties/test/subscriber_test.rb @@ -92,7 +92,7 @@ module SubscriberTest def test_flushes_loggers_when_action_dispatch_callback_is_received Rails::Subscriber.add :my_subscriber, @subscriber - instrument "action_dispatch.callback" + instrument "action_dispatch.after_dispatch" wait assert_equal 1, @logger.flush_count end @@ -100,7 +100,7 @@ module SubscriberTest def test_flushes_the_same_logger_just_once Rails::Subscriber.add :my_subscriber, @subscriber Rails::Subscriber.add :another, @subscriber - instrument "action_dispatch.callback" + instrument "action_dispatch.after_dispatch" wait assert_equal 1, @logger.flush_count end @@ -111,7 +111,7 @@ module SubscriberTest Rails::Subscriber.log_tailer = log_tailer Rails::Subscriber.add :my_subscriber, @subscriber - instrument "action_dispatch.callback" + instrument "action_dispatch.after_dispatch" wait ensure Rails::Subscriber.log_tailer = nil |