aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG22
-rwxr-xr-xrailties/bin/rails2
-rw-r--r--railties/guides/assets/images/radar.pngbin0 -> 19521 bytes
-rw-r--r--railties/guides/assets/images/vijaydev.jpgbin0 -> 4610 bytes
-rw-r--r--railties/guides/rails_guides/helpers.rb2
-rw-r--r--railties/guides/source/3_0_release_notes.textile42
-rw-r--r--railties/guides/source/action_controller_overview.textile2
-rw-r--r--railties/guides/source/action_mailer_basics.textile31
-rw-r--r--railties/guides/source/action_view_overview.textile117
-rw-r--r--railties/guides/source/active_record_basics.textile4
-rw-r--r--railties/guides/source/active_record_querying.textile113
-rw-r--r--railties/guides/source/active_record_validations_callbacks.textile161
-rw-r--r--railties/guides/source/active_support_core_extensions.textile124
-rw-r--r--railties/guides/source/ajax_on_rails.textile2
-rw-r--r--railties/guides/source/api_documentation_guidelines.textile8
-rw-r--r--railties/guides/source/asset_pipeline.textile335
-rw-r--r--railties/guides/source/association_basics.textile4
-rw-r--r--railties/guides/source/caching_with_rails.textile11
-rw-r--r--railties/guides/source/command_line.textile335
-rw-r--r--railties/guides/source/configuring.textile195
-rw-r--r--railties/guides/source/contribute.textile6
-rw-r--r--railties/guides/source/contributing_to_ruby_on_rails.textile12
-rw-r--r--railties/guides/source/credits.html.erb24
-rw-r--r--railties/guides/source/debugging_rails_applications.textile26
-rw-r--r--railties/guides/source/form_helpers.textile8
-rw-r--r--railties/guides/source/generators.textile6
-rw-r--r--railties/guides/source/getting_started.textile59
-rw-r--r--railties/guides/source/i18n.textile2
-rw-r--r--railties/guides/source/initialization.textile627
-rw-r--r--railties/guides/source/layouts_and_rendering.textile2
-rw-r--r--railties/guides/source/migrations.textile10
-rw-r--r--railties/guides/source/nested_model_forms.textile12
-rw-r--r--railties/guides/source/performance_testing.textile12
-rw-r--r--railties/guides/source/plugins.textile39
-rw-r--r--railties/guides/source/rails_application_templates.textile10
-rw-r--r--railties/guides/source/rails_on_rack.textile12
-rw-r--r--railties/guides/source/routing.textile4
-rw-r--r--railties/guides/source/ruby_on_rails_guides_guidelines.textile6
-rw-r--r--railties/guides/source/security.textile20
-rw-r--r--railties/guides/source/testing.textile6
-rw-r--r--railties/lib/rails.rb26
-rw-r--r--railties/lib/rails/all.rb1
-rw-r--r--railties/lib/rails/application.rb31
-rw-r--r--railties/lib/rails/application/configuration.rb2
-rw-r--r--railties/lib/rails/application/railties.rb2
-rw-r--r--railties/lib/rails/code_statistics.rb2
-rw-r--r--railties/lib/rails/commands.rb8
-rw-r--r--railties/lib/rails/commands/benchmarker.rb6
-rw-r--r--railties/lib/rails/commands/generate.rb4
-rw-r--r--railties/lib/rails/commands/plugin.rb4
-rw-r--r--railties/lib/rails/commands/profiler.rb6
-rw-r--r--railties/lib/rails/commands/runner.rb4
-rw-r--r--railties/lib/rails/commands/server.rb2
-rw-r--r--railties/lib/rails/engine.rb44
-rw-r--r--railties/lib/rails/engine/commands.rb38
-rw-r--r--railties/lib/rails/generators.rb7
-rw-r--r--railties/lib/rails/generators/actions.rb8
-rw-r--r--railties/lib/rails/generators/app_base.rb63
-rw-r--r--railties/lib/rails/generators/base.rb6
-rw-r--r--railties/lib/rails/generators/generated_attribute.rb2
-rw-r--r--railties/lib/rails/generators/js/assets/assets_generator.rb13
-rw-r--r--railties/lib/rails/generators/js/assets/templates/javascript.js2
-rw-r--r--railties/lib/rails/generators/named_base.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile14
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt12
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css12
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb12
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml62
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml17
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/routes.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb2
-rw-r--r--railties/lib/rails/generators/rails/assets/USAGE2
-rw-r--r--railties/lib/rails/generators/rails/assets/assets_generator.rb11
-rw-r--r--railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee3
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb20
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec3
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/Gemfile9
-rwxr-xr-xrailties/lib/rails/generators/rails/plugin_new/templates/Rakefile9
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt14
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb2
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb8
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt8
-rw-r--r--railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb2
-rw-r--r--railties/lib/rails/info.rb4
-rw-r--r--railties/lib/rails/railtie.rb13
-rw-r--r--railties/lib/rails/railtie/configurable.rb2
-rw-r--r--railties/lib/rails/source_annotation_extractor.rb8
-rw-r--r--railties/lib/rails/tasks.rb1
-rw-r--r--railties/lib/rails/tasks/assets.rake10
-rw-r--r--railties/lib/rails/tasks/documentation.rake8
-rw-r--r--railties/lib/rails/tasks/engine.rake2
-rw-r--r--railties/lib/rails/test_unit/testing.rake8
-rw-r--r--railties/lib/rails/version.rb4
-rw-r--r--railties/railties.gemspec4
-rw-r--r--railties/test/abstract_unit.rb1
-rw-r--r--railties/test/application/assets_test.rb46
-rw-r--r--railties/test/application/configuration_test.rb25
-rw-r--r--railties/test/application/console_test.rb6
-rw-r--r--railties/test/application/generators_test.rb4
-rw-r--r--railties/test/application/initializers/boot_test.rb6
-rw-r--r--railties/test/application/initializers/check_ruby_version_test.rb4
-rw-r--r--railties/test/application/initializers/frameworks_test.rb4
-rw-r--r--railties/test/application/initializers/hooks_test.rb4
-rw-r--r--railties/test/application/initializers/i18n_test.rb10
-rw-r--r--railties/test/application/initializers/load_path_test.rb4
-rw-r--r--railties/test/application/initializers/notifications_test.rb4
-rw-r--r--railties/test/application/loading_test.rb4
-rw-r--r--railties/test/application/middleware/best_practices_test.rb4
-rw-r--r--railties/test/application/middleware/cache_test.rb4
-rw-r--r--railties/test/application/middleware/remote_ip_test.rb4
-rw-r--r--railties/test/application/middleware/sendfile_test.rb4
-rw-r--r--railties/test/application/middleware/show_exceptions_test.rb4
-rw-r--r--railties/test/application/middleware_test.rb6
-rw-r--r--railties/test/application/paths_test.rb4
-rw-r--r--railties/test/application/rack/logger_test.rb4
-rw-r--r--railties/test/application/rackup_test.rb4
-rw-r--r--railties/test/application/rake_test.rb43
-rw-r--r--railties/test/application/routing_test.rb4
-rw-r--r--railties/test/application/runner_test.rb8
-rw-r--r--railties/test/application/test_test.rb4
-rw-r--r--railties/test/fixtures/lib/generators/wrong_generator.rb3
-rw-r--r--railties/test/generators/app_generator_test.rb50
-rw-r--r--railties/test/generators/assets_generator_test.rb10
-rw-r--r--railties/test/generators/controller_generator_test.rb2
-rw-r--r--railties/test/generators/generated_attribute_test.rb13
-rw-r--r--railties/test/generators/model_generator_test.rb12
-rw-r--r--railties/test/generators/namespaced_generators_test.rb10
-rw-r--r--railties/test/generators/plugin_new_generator_test.rb85
-rw-r--r--railties/test/generators/scaffold_generator_test.rb33
-rw-r--r--railties/test/generators/shared_generator_tests.rb4
-rw-r--r--railties/test/generators_test.rb6
-rw-r--r--railties/test/isolation/abstract_unit.rb13
-rw-r--r--railties/test/railties/engine_test.rb20
-rw-r--r--railties/test/railties/generators_test.rb116
-rw-r--r--railties/test/railties/mounted_engine_test.rb7
-rw-r--r--railties/test/railties/plugin_ordering_test.rb6
-rw-r--r--railties/test/railties/plugin_test.rb4
-rw-r--r--railties/test/railties/railtie_test.rb4
-rw-r--r--railties/test/railties/shared_tests.rb28
148 files changed, 2386 insertions, 1280 deletions
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index c465b08594..a9b4deb551 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -1,18 +1,26 @@
+*Rails 3.2.0 (unreleased)*
+
+* Attributes on scaffold and model generators default to string. This allows the following: "rails g scaffold Post title body:text author" [José Valim]
+
+* Removed old plugin generator (`rails generate plugin`) in favor of `rails plugin new` command. [Guillermo Iguaran]
+
+* Removed old 'config.paths.app.controller' API in favor of 'config.paths["app/controller"]' API. [Guillermo Iguaran]
+
*Rails 3.1.0 (unreleased)*
-* Application and plugin generation run bundle install unless --skip-gemfile or --skip-bundle. [fxn]
+* Make sprockets/railtie require explicit and add --skip-sprockets to app generator [José Valim]
-* Fixed database tasks for jdbc* adapters #jruby
+* Added Rails.groups that automatically handles Rails.env and ENV["RAILS_GROUPS"] [José Valim]
- [Rashmi Yadav]
+* The new rake task assets:clean removes precompiled assets. [fxn]
-* Template generation for jdbcpostgresql #jruby
+* Application and plugin generation run bundle install unless --skip-gemfile or --skip-bundle. [fxn]
- [Vishnu Atrai]
+* Fixed database tasks for jdbc* adapters #jruby [Rashmi Yadav]
-* Template generation for jdbcmysql and jdbcsqlite3 #jruby
+* Template generation for jdbcpostgresql #jruby [Vishnu Atrai]
- [Arun Agrawal]
+* Template generation for jdbcmysql and jdbcsqlite3 #jruby [Arun Agrawal]
* The -j option of the application generator accepts an arbitrary string. If passed "foo",
the gem "foo-rails" is added to the Gemfile, and the application JavaScript manifest
diff --git a/railties/bin/rails b/railties/bin/rails
new file mode 100755
index 0000000000..a7d6938e0d
--- /dev/null
+++ b/railties/bin/rails
@@ -0,0 +1,2 @@
+#!/usr/bin/env ruby
+require "rails/cli" \ No newline at end of file
diff --git a/railties/guides/assets/images/radar.png b/railties/guides/assets/images/radar.png
new file mode 100644
index 0000000000..f61e08763f
--- /dev/null
+++ b/railties/guides/assets/images/radar.png
Binary files differ
diff --git a/railties/guides/assets/images/vijaydev.jpg b/railties/guides/assets/images/vijaydev.jpg
new file mode 100644
index 0000000000..e21d3cabfc
--- /dev/null
+++ b/railties/guides/assets/images/vijaydev.jpg
Binary files differ
diff --git a/railties/guides/rails_guides/helpers.rb b/railties/guides/rails_guides/helpers.rb
index d466c76c7c..463df8a7a8 100644
--- a/railties/guides/rails_guides/helpers.rb
+++ b/railties/guides/rails_guides/helpers.rb
@@ -15,7 +15,7 @@ module RailsGuides
def author(name, nick, image = 'credits_pic_blank.gif', &block)
image = "images/#{image}"
- result = content_tag(:img, nil, :src => image, :class => 'left pic', :alt => name)
+ result = content_tag(:img, nil, :src => image, :class => 'left pic', :alt => name, :width => 91, :height => 91)
result << content_tag(:h3, name)
result << content_tag(:p, capture(&block))
content_tag(:div, result, :class => 'clearfix', :id => nick)
diff --git a/railties/guides/source/3_0_release_notes.textile b/railties/guides/source/3_0_release_notes.textile
index f75b245ed8..fbb684978a 100644
--- a/railties/guides/source/3_0_release_notes.textile
+++ b/railties/guides/source/3_0_release_notes.textile
@@ -61,7 +61,7 @@ h4. Upgrade Process
To help with the upgrade process, a plugin named "Rails Upgrade":http://github.com/jm/rails_upgrade has been created to automate part of it.
-Simply install the plugin, then run +rake rails:upgrade:check+ to check your app for pieces that need to be updated (with links to information on how to update them). It also offers a task to generate a +Gemfile+ based on your current +config.gem+ calls and a task to generate a new routes file from your current one. To get the plugin, simply run the following:
+Simply install the plugin, then run +rake rails:upgrade:check+ to check your app for pieces that need to be updated (with links to information on how to update them). It also offers a task to generate a +Gemfile+ based on your current +config.gem+ calls and a task to generate a new routes file from your current one. To get the plugin, simply run the following:
<shell>
$ ruby script/plugin install git://github.com/jm/rails_upgrade.git
@@ -69,7 +69,7 @@ $ ruby script/plugin install git://github.com/jm/rails_upgrade.git
You can see an example of how that works at "Rails Upgrade is now an Official Plugin":http://omgbloglol.com/post/364624593/rails-upgrade-is-now-an-official-plugin
-Aside from Rails Upgrade tool, if you need more help, there are people on IRC and "rubyonrails-talk":http://groups.google.com/group/rubyonrails-talk that are probably doing the same thing, possibly hitting the same issues. Be sure to blog your own experiences when upgrading so others can benefit from your knowledge!
+Aside from Rails Upgrade tool, if you need more help, there are people on IRC and "rubyonrails-talk":http://groups.google.com/group/rubyonrails-talk that are probably doing the same thing, possibly hitting the same issues. Be sure to blog your own experiences when upgrading so others can benefit from your knowledge!
More information - "The Path to Rails 3: Approaching the upgrade":http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade
@@ -113,42 +113,42 @@ Railties was updated to provide a consistent plugin API for the entire Rails fra
h4. All Rails core components are decoupled
-With the merge of Merb and Rails, one of the big jobs was to remove the tight coupling between Rails core components. This has now been achieved, and all Rails core components are now using the same API that you can use for developing plugins. This means any plugin you make, or any core component replacement (like DataMapper or Sequel) can access all the functionality that the Rails core components have access to and extend and enhance at will.
+With the merge of Merb and Rails, one of the big jobs was to remove the tight coupling between Rails core components. This has now been achieved, and all Rails core components are now using the same API that you can use for developing plugins. This means any plugin you make, or any core component replacement (like DataMapper or Sequel) can access all the functionality that the Rails core components have access to and extend and enhance at will.
More information: - "The Great Decoupling":http://yehudakatz.com/2009/07/19/rails-3-the-great-decoupling/
h4. Active Model Abstraction
-Part of decoupling the core components was extracting all ties to Active Record from Action Pack. This has now been completed. All new ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.
+Part of decoupling the core components was extracting all ties to Active Record from Action Pack. This has now been completed. All new ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.
More information: - "Make Any Ruby Object Feel Like ActiveRecord":http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/
h4. Controller Abstraction
-Another big part of decoupling the core components was creating a base superclass that is separated from the notions of HTTP in order to handle rendering of views etc. This creation of +AbstractController+ allowed +ActionController+ and +ActionMailer+ to be greatly simplified with common code removed from all these libraries and put into Abstract Controller.
+Another big part of decoupling the core components was creating a base superclass that is separated from the notions of HTTP in order to handle rendering of views etc. This creation of +AbstractController+ allowed +ActionController+ and +ActionMailer+ to be greatly simplified with common code removed from all these libraries and put into Abstract Controller.
More Information: - "Rails Edge Architecture":http://yehudakatz.com/2009/06/11/rails-edge-architecture/
h4. Arel Integration
-"Arel":http://github.com/brynary/arel (or Active Relation) has been taken on as the underpinnings of Active Record and is now required for Rails. Arel provides an SQL abstraction that simplifies out Active Record and provides the underpinnings for the relation functionality in Active Record.
+"Arel":http://github.com/brynary/arel (or Active Relation) has been taken on as the underpinnings of Active Record and is now required for Rails. Arel provides an SQL abstraction that simplifies out Active Record and provides the underpinnings for the relation functionality in Active Record.
More information: - "Why I wrote Arel":http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-wrote-arel/.
h4. Mail Extraction
-Action Mailer ever since its beginnings has had monkey patches, pre parsers and even delivery and receiver agents, all in addition to having TMail vendored in the source tree. Version 3 changes that with all email message related functionality abstracted out to the "Mail":http://github.com/mikel/mail gem. This again reduces code duplication and helps create definable boundaries between Action Mailer and the email parser.
+Action Mailer ever since its beginnings has had monkey patches, pre parsers and even delivery and receiver agents, all in addition to having TMail vendored in the source tree. Version 3 changes that with all email message related functionality abstracted out to the "Mail":http://github.com/mikel/mail gem. This again reduces code duplication and helps create definable boundaries between Action Mailer and the email parser.
More information: - "New Action Mailer API in Rails 3":http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3
h3. Documentation
-The documentation in the Rails tree is being updated with all the API changes, additionally, the "Rails Edge Guides":http://edgeguides.rubyonrails.org/ are being updated one by one to reflect the changes in Rails 3.0. The guides at "guides.rubyonrails.org":http://guides.rubyonrails.org/ however will continue to contain only the stable version of Rails (at this point, version 2.3.5, until 3.0 is released).
+The documentation in the Rails tree is being updated with all the API changes, additionally, the "Rails Edge Guides":http://edgeguides.rubyonrails.org/ are being updated one by one to reflect the changes in Rails 3.0. The guides at "guides.rubyonrails.org":http://guides.rubyonrails.org/ however will continue to contain only the stable version of Rails (at this point, version 2.3.5, until 3.0 is released).
More Information: - "Rails Documentation Projects":http://weblog.rubyonrails.org/2009/1/15/rails-documentation-projects.
@@ -157,7 +157,7 @@ h3. Internationalization
A large amount of work has been done with I18n support in Rails 3, including the latest "I18n":http://github.com/svenfuchs/i18n gem supplying many speed improvements.
-* I18n for any object - I18n behavior can be added to any object by including <tt>ActiveModel::Translation</tt> and <tt>ActiveModel::Validations</tt>. There is also an <tt>errors.messages</tt> fallback for translations.
+* I18n for any object - I18n behavior can be added to any object by including <tt>ActiveModel::Translation</tt> and <tt>ActiveModel::Validations</tt>. There is also an <tt>errors.messages</tt> fallback for translations.
* Attributes can have default translations.
* Form Submit Tags automatically pull the correct status (Create or Update) depending on the object status, and so pull the correct translation.
* Labels with I18n also now work by just passing the attribute name.
@@ -173,7 +173,7 @@ With the decoupling of the main Rails frameworks, Railties got a huge overhaul s
* Anything under <tt>Rails.root/app</tt> is now added to the load path, so you can make <tt>app/observers/user_observer.rb</tt> and Rails will load it without any modifications.
* Rails 3.0 now provides a <tt>Rails.config</tt> object, which provides a central repository of all sorts of Rails wide configuration options.
-Application generation has received extra flags allowing you to skip the installation of test-unit, Active Record, Prototype and Git. Also a new <tt>--dev</tt> flag has been added which sets the application up with the +Gemfile+ pointing to your Rails checkout (which is determined by the path to the +rails+ binary). See <tt>rails --help</tt> for more info.
+Application generation has received extra flags allowing you to skip the installation of test-unit, Active Record, Prototype and Git. Also a new <tt>--dev</tt> flag has been added which sets the application up with the +Gemfile+ pointing to your Rails checkout (which is determined by the path to the +rails+ binary). See <tt>rails --help</tt> for more info.
Railties generators got a huge amount of attention in Rails 3.0, basically:
@@ -215,7 +215,7 @@ There have been significant internal and external changes in Action Pack.
h4. Abstract Controller
-Abstract Controller pulls out the generic parts of Action Controller into a reusable module that any library can use to render templates, render partials, helpers, translations, logging, any part of the request response cycle. This abstraction allowed <tt>ActionMailer::Base</tt> to now just inherit from +AbstractController+ and just wrap the Rails DSL onto the Mail gem.
+Abstract Controller pulls out the generic parts of Action Controller into a reusable module that any library can use to render templates, render partials, helpers, translations, logging, any part of the request response cycle. This abstraction allowed <tt>ActionMailer::Base</tt> to now just inherit from +AbstractController+ and just wrap the Rails DSL onto the Mail gem.
It also provided an opportunity to clean up Action Controller, abstracting out what could to simplify the code.
@@ -231,7 +231,7 @@ h4. Action Controller
* The <tt>session_store</tt> was configured in <tt>ActionController::Base.session</tt>, and that is now moved to <tt>Rails.application.config.session_store</tt>. Defaults are set up in <tt>config/initializers/session_store.rb</tt>.
* <tt>cookies.secure</tt> allowing you to set encrypted values in cookies with <tt>cookie.secure[:key] => value</tt>.
* <tt>cookies.permanent</tt> allowing you to set permanent values in the cookie hash <tt>cookie.permanent[:key] => value</tt> that raise exceptions on signed values if verification failures.
-* You can now pass <tt>:notice => 'This is a flash message'</tt> or <tt>:alert => 'Something went wrong'</tt> to the <tt>format</tt> call inside a +respond_to+ block. The <tt>flash[]</tt> hash still works as previously.
+* You can now pass <tt>:notice => 'This is a flash message'</tt> or <tt>:alert => 'Something went wrong'</tt> to the <tt>format</tt> call inside a +respond_to+ block. The <tt>flash[]</tt> hash still works as previously.
* <tt>respond_with</tt> method has now been added to your controllers simplifying the venerable +format+ blocks.
* <tt>ActionController::Responder</tt> added allowing you flexibility in how your responses get generated.
@@ -298,9 +298,9 @@ h4. Action View
h5. Unobtrusive JavaScript
-Major re-write was done in the Action View helpers, implementing Unobtrusive JavaScript (UJS) hooks and removing the old inline AJAX commands. This enables Rails to use any compliant UJS driver to implement the UJS hooks in the helpers.
+Major re-write was done in the Action View helpers, implementing Unobtrusive JavaScript (UJS) hooks and removing the old inline AJAX commands. This enables Rails to use any compliant UJS driver to implement the UJS hooks in the helpers.
-What this means is that all previous <tt>remote_&lt;method&gt;</tt> helpers have been removed from Rails core and put into the "Prototype Legacy Helper":http://github.com/rails/prototype_legacy_helper. To get UJS hooks into your HTML, you now pass <tt>:remote => true</tt> instead. For example:
+What this means is that all previous <tt>remote_&lt;method&gt;</tt> helpers have been removed from Rails core and put into the "Prototype Legacy Helper":http://github.com/rails/prototype_legacy_helper. To get UJS hooks into your HTML, you now pass <tt>:remote => true</tt> instead. For example:
<ruby>
form_for @post, :remote => true
@@ -341,12 +341,12 @@ h5. Other Changes
h3. Active Model
-Active Model is new in Rails 3.0. It provides an abstraction layer for any ORM libraries to use to interact with Rails by implementing an Active Model interface.
+Active Model is new in Rails 3.0. It provides an abstraction layer for any ORM libraries to use to interact with Rails by implementing an Active Model interface.
h4. ORM Abstraction and Action Pack Interface
-Part of decoupling the core components was extracting all ties to Active Record from Action Pack. This has now been completed. All new ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.
+Part of decoupling the core components was extracting all ties to Active Record from Action Pack. This has now been completed. All new ORM plugins now just need to implement Active Model interfaces to work seamlessly with Action Pack.
More Information: - "Make Any Ruby Object Feel Like ActiveRecord":http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/
@@ -410,12 +410,12 @@ More Information:
h3. Active Record
-Active Record received a lot of attention in Rails 3.0, including abstraction into Active Model, a full update to the Query interface using Arel, validation updates and many enhancements and fixes. All of the Rails 2.x API will be usable through a compatibility layer that will be supported until version 3.1.
+Active Record received a lot of attention in Rails 3.0, including abstraction into Active Model, a full update to the Query interface using Arel, validation updates and many enhancements and fixes. All of the Rails 2.x API will be usable through a compatibility layer that will be supported until version 3.1.
h4. Query Interface
-Active Record, through the use of Arel, now returns relations on its core methods. The existing API in Rails 2.3.x is still supported and will not be deprecated until Rails 3.1 and not removed until Rails 3.2, however, the new API provides the following new methods that all return relations allowing them to be chained together:
+Active Record, through the use of Arel, now returns relations on its core methods. The existing API in Rails 2.3.x is still supported and will not be deprecated until Rails 3.1 and not removed until Rails 3.2, however, the new API provides the following new methods that all return relations allowing them to be chained together:
* <tt>where</tt> - provides conditions on the relation, what gets returned.
* <tt>select</tt> - choose what attributes of the models you wish to have returned from the database.
@@ -502,7 +502,7 @@ Deprecations:
h3. Active Support
-A large effort was made in Active Support to make it cherry pickable, that is, you no longer have to require the entire Active Support library to get pieces of it. This allows the various core components of Rails to run slimmer.
+A large effort was made in Active Support to make it cherry pickable, that is, you no longer have to require the entire Active Support library to get pieces of it. This allows the various core components of Rails to run slimmer.
These are the main changes in Active Support:
@@ -559,7 +559,7 @@ The following methods have been removed because they are no longer used in the f
h3. Action Mailer
-Action Mailer has been given a new API with TMail being replaced out with the new "Mail":http://github.com/mikel/mail as the Email library. Action Mailer itself has been given an almost complete re-write with pretty much every line of code touched. The result is that Action Mailer now simply inherits from Abstract Controller and wraps the Mail gem in a Rails DSL. This reduces the amount of code and duplication of other libraries in Action Mailer considerably.
+Action Mailer has been given a new API with TMail being replaced out with the new "Mail":http://github.com/mikel/mail as the Email library. Action Mailer itself has been given an almost complete re-write with pretty much every line of code touched. The result is that Action Mailer now simply inherits from Abstract Controller and wraps the Mail gem in a Rails DSL. This reduces the amount of code and duplication of other libraries in Action Mailer considerably.
* All mailers are now in <tt>app/mailers</tt> by default.
* Can now send email using new API with three methods: +attachments+, +headers+ and +mail+.
@@ -589,7 +589,7 @@ More Information:
h3. Credits
-See the "full list of contributors to Rails":http://contributors.rubyonrails.org/ for the many people who spent many hours making Rails 3. Kudos to all of them.
+See the "full list of contributors to Rails":http://contributors.rubyonrails.org/ for the many people who spent many hours making Rails 3. Kudos to all of them.
Rails 3.0 Release Notes were compiled by "Mikel Lindsaar":http://lindsaar.net.
diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile
index 891bae3d5e..073e3bddcf 100644
--- a/railties/guides/source/action_controller_overview.textile
+++ b/railties/guides/source/action_controller_overview.textile
@@ -802,7 +802,7 @@ class DinnerController
end
</ruby>
-Just like the filter, you could also passing +:only+ and +:except+ to enforce the secure connection only to specific actions
+Just like the filter, you could also passing +:only+ and +:except+ to enforce the secure connection only to specific actions.
<ruby>
class DinnerController
diff --git a/railties/guides/source/action_mailer_basics.textile b/railties/guides/source/action_mailer_basics.textile
index a6ff8f877d..2eaee158ff 100644
--- a/railties/guides/source/action_mailer_basics.textile
+++ b/railties/guides/source/action_mailer_basics.textile
@@ -104,7 +104,7 @@ When you call the +mail+ method now, Action Mailer will detect the two templates
h5. Wire It Up So That the System Sends the Email When a User Signs Up
-There are several ways to do this, some people create Rails Observers to fire off emails, others do it inside of the User Model. However, in Rails 3, mailers are really just another way to render a view. Instead of rendering a view and sending out the HTTP protocol, they are just sending it out through the Email protocols instead. Due to this, it makes sense to just have your controller tell the mailer to send an email when a user is successfully created.
+There are several ways to do this, some people create Rails Observers to fire off emails, others do it inside of the User Model. However, in Rails 3, mailers are really just another way to render a view. Instead of rendering a view and sending out the HTTP protocol, they are just sending it out through the Email protocols instead. Due to this, it makes sense to just have your controller tell the mailer to send an email when a user is successfully created.
Setting this up is painfully simple.
@@ -284,16 +284,37 @@ class UserMailer < ActionMailer::Base
@user = user
@url = "http://example.com/login"
mail(:to => user.email,
+ :subject => "Welcome to My Awesome Site",
+ :template_path => 'notifications',
+ :template_name => 'another')
+ end
+ end
+
+end
+</ruby>
+
+In this case it will look for templates at +app/views/notifications+ with name +another+.
+
+If you want more flexibility you can also pass a block and render specific templates or even render inline or text without using a template file:
+
+<ruby>
+class UserMailer < ActionMailer::Base
+ default :from => "notifications@example.com"
+
+ def welcome_email(user)
+ @user = user
+ @url = "http://example.com/login"
+ mail(:to => user.email,
:subject => "Welcome to My Awesome Site") do |format|
format.html { render 'another_template' }
- format.text { render 'another_template' }
+ format.text { render :text => 'Render text' }
end
end
end
</ruby>
-Will render 'another_template.text.erb' and 'another_template.html.erb'. The render command is the same one used inside of Action Controller, so you can use all the same options, such as <tt>:text</tt> etc.
+This will render the template 'another_template.html.erb' for the HTML part and use the rendered text for the text part. The render command is the same one used inside of Action Controller, so you can use all the same options, such as <tt>:text</tt>, <tt>:inline</tt> etc.
h4. Action Mailer Layouts
@@ -363,7 +384,7 @@ h4. Sending Multipart Emails
Action Mailer will automatically send multipart emails if you have different templates for the same action. So, for our UserMailer example, if you have +welcome_email.text.erb+ and +welcome_email.html.erb+ in +app/views/user_mailer+, Action Mailer will automatically send a multipart email with the HTML and text versions setup as different parts.
-The order of the parts getting inserted is determined by the <tt>:parts_order</tt> inside of the <tt>ActionMailer::Base.default</tt> method. If you want to explicitly alter the order, you can either change the <tt>:parts_order</tt> or explicitly render the parts in a different order:
+The order of the parts getting inserted is determined by the <tt>:parts_order</tt> inside of the <tt>ActionMailer::Base.default</tt> method. If you want to explicitly alter the order, you can either change the <tt>:parts_order</tt> or explicitly render the parts in a different order:
<ruby>
class UserMailer < ActionMailer::Base
@@ -419,7 +440,7 @@ class UserMailer < ActionMailer::Base
)
if email.has_attachments?
- for attachment in email.attachments
+ email.attachments.each do |attachment|
page.attachments.create({
:file => attachment,
:description => email.subject
diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile
index 2b2c197f46..7703d6c720 100644
--- a/railties/guides/source/action_view_overview.textile
+++ b/railties/guides/source/action_view_overview.textile
@@ -165,7 +165,7 @@ will produce
<em>emphasized</em>
<em><b>emph &amp; bold</b></em>
<a href="http://rubyonrails.org">A link</a>
-<target option="fast" name="compile" \>
+<target option="fast" name="compile" />
</html>
Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
@@ -211,7 +211,7 @@ xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
end
</ruby>
-h5. Template caching
+h5. Template Caching
By default, Rails will compile each template to a method in order to render it. When you alter a template, Rails will check the file's modification time and recompile it in development mode.
@@ -235,7 +235,7 @@ This will render a file named +_menu.html.erb+ at that point within the view is
That code will pull in the partial from +app/views/shared/_menu.html.erb+.
-h5. Using Partials to Simplify Views
+h5. Using Partials to simplify Views
One way to use partials is to treat them as the equivalent of subroutines: as a way to move details out of a view so that you can grasp what's going on more easily. For example, you might have a view that looked like this:
@@ -615,7 +615,7 @@ atom_feed do |feed|
feed.title("Posts Index")
feed.updated((@posts.first.created_at))
- for post in @posts
+ @posts.each do |post|
feed.entry(post) do |entry|
entry.title(post.title)
entry.content(post.body, :type => 'html')
@@ -929,7 +929,7 @@ Creates a scope around a specific model object like form_for, but doesn‘t crea
h5. file_field
-Returns an file upload input tag tailored for accessing a specified attribute.
+Returns a file upload input tag tailored for accessing a specified attribute.
<ruby>
file_field(:user, :avatar)
@@ -1037,7 +1037,7 @@ Sample usage (selecting the associated Author for an instance of Post, +@post+):
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, {:prompt => true})
</ruby>
-If @post.author_id is already 1, this would return:
+If <tt>@post.author_id</tt> is 1, this would return:
<html>
<select name="post[author_id]">
@@ -1080,8 +1080,6 @@ Sample usage:
option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)
</ruby>
-TODO check above textile output looks right
-
Possible output:
<html>
@@ -1132,13 +1130,13 @@ h5. select
Create a select tag and a series of contained option tags for the provided object and method.
-Example with @post.person_id => 1:
+Example:
<ruby>
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { :include_blank => true })
</ruby>
-could become:
+If <tt>@post.person_id</tt> is 1, this would become:
<html>
<select name="post[person_id]">
@@ -1189,7 +1187,7 @@ h5. file_field_tag
Creates a file upload field.
-If you are using file uploads then you will also need to set the multipart option for the form tag:
+Prior to Rails 3.1, if you are using file uploads, then you will need to set the multipart option for the form tag. Rails 3.1+ does this automatically.
<ruby>
<%= form_tag { :action => "post" }, { :multipart => true } do %>
@@ -1400,102 +1398,6 @@ number_with_precision(111.2345) # => 111.235
number_with_precision(111.2345, 2) # => 111.23
</ruby>
-h5. evaluate_remote_response
-
-Returns +eval(request.responseText)+ which is the JavaScript function that form_remote_tag can call in +:complete+ to evaluate a multiple update return document using +update_element_function+ calls.
-
-h5. form_remote_tag
-
-Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement. Even though it‘s using JavaScript to serialize the form elements, the form submission will work just like a regular submission as viewed by the receiving side.
-
-For example, this:
-
-<ruby>
-form_remote_tag :html => { :action => url_for(:controller => "some", :action => "place") }
-</ruby>
-
-would generate the following:
-
-<html>
-<form action="/some/place" method="post" onsubmit="new Ajax.Request('',
- {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
-</html>
-
-h5. link_to_remote
-
-Returns a link to a remote action that's called in the background using XMLHttpRequest. You can generate a link that uses AJAX in the general case, while degrading gracefully to plain link behavior in the absence of JavaScript. For example:
-
-<ruby>
-link_to_remote "Delete this post",
- { :update => "posts", :url => { :action => "destroy", :id => post.id } },
- :href => url_for(:action => "destroy", :id => post.id)
-</ruby>
-
-h5. observe_field
-
-Observes the field specified and calls a callback when its contents have changed.
-
-<ruby>
-observe_field("my_field", :function => "alert('Field changed')")
-</ruby>
-
-h5. observe_form
-
-Observes the form specified and calls a callback when its contents have changed. The options for observe_form are the same as the options for observe_field.
-
-<ruby>
-observe_field("my_form", :function => "alert('Form changed')")
-</ruby>
-
-h5. periodically_call_remote
-
-Periodically calls the specified url as often as specified. Usually used to update a specified div with the results of the remote call. The following example will call update every 20 seconds and update the news_block div:
-
-<ruby>
-periodically_call_remote(:url => 'update', :frequency => '20', :update => 'news_block')
-# => PeriodicalExecuter(function() {new Ajax.Updater('news_block', 'update', {asynchronous:true, evalScripts:true})}, 20)
-</ruby>
-
-h5. remote_form_for
-
-Creates a form that will submit using XMLHttpRequest in the background instead of the regular reloading POST arrangement and a scope around a specific resource that is used as a base for questioning about values for the fields.
-
-<ruby>
-<%= remote_form_for(@post) do |f| %>
- ...
-<% end %>
-</ruby>
-
-h5. remote_function
-
-Returns the JavaScript needed for a remote function. Takes the same arguments as +link_to_remote+.
-
-<ruby>
-<select id="options" onchange="<%= remote_function(:update => "options", :url => { :action => :update_options }) %>">
- <option value="0">Hello</option>
- <option value="1">World</option>
-</select>
-# => <select id="options" onchange="new Ajax.Updater('options', '/testing/update_options', {asynchronous:true, evalScripts:true})">
-</ruby>
-
-h5. submit_to_remote
-
-Returns a button input tag that will submit form using XMLHttpRequest in the background instead of a regular POST request that reloads the page.
-
-For example, the following:
-
-<ruby>
-submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' }
-</ruby>
-
-would generate:
-
-<html>
-<input name="create_btn" onclick="new Ajax.Request('/testing/create',
- {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
- return false;" type="button" value="Create" />
-</html>
-
h3. Localized Views
Action View has the ability render different templates depending on the current locale.
@@ -1520,6 +1422,7 @@ You can read more about the Rails Internationalization (I18n) API "here":i18n.ht
h3. Changelog
+* May 29, 2011: Removed references to remote_* helpers - Vijay Dev
* April 16, 2011: Added 'Using Action View with Rails', 'Templates' and 'Partials' sections. "Sebastian Martinez":http://wyeworks.com
* September 3, 2009: Continuing work by Trevor Turk, leveraging the Action Pack docs and "What's new in Edge Rails":http://ryandaigle.com/articles/2007/8/3/what-s-new-in-edge-rails-partials-get-layouts
* April 5, 2009: Starting work by Trevor Turk, leveraging Mike Gunderloy's docs
diff --git a/railties/guides/source/active_record_basics.textile b/railties/guides/source/active_record_basics.textile
index b7926f3a3b..3e46e7df9f 100644
--- a/railties/guides/source/active_record_basics.textile
+++ b/railties/guides/source/active_record_basics.textile
@@ -64,8 +64,8 @@ There are also some optional column names that will create additional features t
* *created_on* - Automatically gets set to the current date when the record is first created.
* *updated_at* - Automatically gets set to the current date and time whenever the record is updated.
* *updated_on* - Automatically gets set to the current date whenever the record is updated.
-* *lock_version* - Adds "optimistic locking":http://api.rubyonrails.com/classes/ActiveRecord/Locking.html to a model.
-* *type* - Specifies that the model uses "Single Table Inheritance":http://api.rubyonrails.com/classes/ActiveRecord/Base.html
+* *lock_version* - Adds "optimistic locking":http://api.rubyonrails.org/classes/ActiveRecord/Locking.html to a model.
+* *type* - Specifies that the model uses "Single Table Inheritance":http://api.rubyonrails.org/classes/ActiveRecord/Base.html
* *(table_name)_count* - Used to cache the number of belonging objects on associations. For example, a +comments_count+ column in a +Post+ class that has many instances of +Comment+ will cache the number of existent comments for each post.
NOTE: While these column names are optional they are in fact reserved by Active Record. Steer clear of reserved keywords unless you want the extra functionality. For example, "type" is a reserved keyword used to designate a table using Single Table Inheritance. If you are not using STI, try an analogous keyword like "context", that may still accurately describe the data you are modeling.
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index 579a323d57..082f9eda7d 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -57,6 +57,7 @@ The methods are:
* +group+
* +order+
* +reorder+
+* +reverse_order+
* +limit+
* +offset+
* +joins+
@@ -255,7 +256,7 @@ The above will yield the supplied block with +1000+ invoices every time.
h3. Conditions
-The +find+ method allows you to specify conditions to limit the records returned, representing the +WHERE+-part of the SQL statement. Conditions can either be specified as a string, array, or hash.
+The +where+ method allows you to specify conditions to limit the records returned, representing the +WHERE+-part of the SQL statement. Conditions can either be specified as a string, array, or hash.
h4. Pure String Conditions
@@ -465,7 +466,7 @@ To apply a +GROUP BY+ clause to the SQL fired by the finder, you can specify the
For example, if you want to find a collection of the dates orders were created on:
<ruby>
-Order.group("date(created_at)").order("created_at")
+Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)")
</ruby>
And this will give you a single +Order+ object for each date where there are orders in the database.
@@ -473,7 +474,7 @@ And this will give you a single +Order+ object for each date where there are ord
The SQL that would be executed would be something like this:
<sql>
-SELECT * FROM orders GROUP BY date(created_at) ORDER BY created_at
+SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at)
</sql>
h3. Having
@@ -483,16 +484,16 @@ SQL uses the +HAVING+ clause to specify conditions on the +GROUP BY+ fields. You
For example:
<ruby>
-Order.group("date(created_at)").having("created_at > ?", 1.month.ago)
+Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)").having("sum(price) > ?", 100)
</ruby>
The SQL that would be executed would be something like this:
<sql>
-SELECT * FROM orders GROUP BY date(created_at) HAVING created_at > '2009-01-15'
+SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at) HAVING sum(price) > 100
</sql>
-This will return single order objects for each day, but only for the last month.
+This will return single order objects for each day, but only those that are ordered more than $100 in a day.
h3. Overriding Conditions
@@ -550,6 +551,32 @@ In case the +reorder+ clause is not used, the SQL executed would be:
SELECT * FROM posts WHERE id = 10 ORDER BY posted_at DESC
</sql>
+h4. +reverse_order+
+
+The +reverse_order+ method reverses the ordering clause if specified.
+
+<ruby>
+Client.where("orders_count > 10").order(:name).reverse_order
+</ruby>
+
+The SQL that would be executed:
+<sql>
+SELECT * FROM clients WHERE orders_count > 10 ORDER BY name DESC
+</sql>
+
+If no ordering clause is specified in the query, the +reverse_order+ orders by the primary key in reverse order.
+
+<ruby>
+Client.where("orders_count > 10").reverse_order
+</ruby>
+
+The SQL that would be executed:
+<sql>
+SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC
+</sql>
+
+This method accepts *no* arguments.
+
h3. Readonly Objects
Active Record provides +readonly+ method on a relation to explicitly disallow modification or deletion of any of the returned object. Any attempt to alter or destroy a readonly record will not succeed, raising an +ActiveRecord::ReadOnlyRecord+ exception.
@@ -675,7 +702,7 @@ class Post < ActiveRecord::Base
has_many :tags
end
-class Comments < ActiveRecord::Base
+class Comment < ActiveRecord::Base
belongs_to :post
has_one :guest
end
@@ -683,6 +710,10 @@ end
class Guest < ActiveRecord::Base
belongs_to :comment
end
+
+class Tag < ActiveRecord::Base
+ belongs_to :post
+end
</ruby>
Now all of the following will produce the expected join queries using +INNER JOIN+:
@@ -700,6 +731,8 @@ SELECT categories.* FROM categories
INNER JOIN posts ON posts.category_id = categories.id
</sql>
+Or, in English: "return a Category object for all categories with posts". Note that you will see duplicate categories if more than one post has the same category. If you want unique categories, you can use Category.joins(:post).select("distinct(categories.id)").
+
h5. Joining Multiple Associations
<ruby>
@@ -714,18 +747,40 @@ SELECT posts.* FROM posts
INNER JOIN comments ON comments.post_id = posts.id
</sql>
+Or, in English: "return all posts that have a category and at least one comment". Note again that posts with multiple comments will show up multiple times.
+
h5. Joining Nested Associations (Single Level)
<ruby>
Post.joins(:comments => :guest)
</ruby>
+This produces:
+
+<sql>
+SELECT posts.* FROM posts
+ INNER JOIN comments ON comments.post_id = posts.id
+ INNER JOIN guests ON guests.comment_id = comments.id
+</sql>
+
+Or, in English: "return all posts that have a comment made by a guest."
+
h5. Joining Nested Associations (Multiple Level)
<ruby>
Category.joins(:posts => [{:comments => :guest}, :tags])
</ruby>
+This produces:
+
+<sql>
+SELECT categories.* FROM categories
+ INNER JOIN posts ON posts.category_id = categories.id
+ INNER JOIN comments ON comments.post_id = posts.id
+ INNER JOIN guests ON guests.comment_id = comments.id
+ INNER JOIN tags ON tags.post_id = posts.id
+</sql>
+
h4. Specifying Conditions on the Joined Tables
You can specify conditions on the joined tables using the regular "Array":#array-conditions and "String":#pure-string-conditions conditions. "Hash conditions":#hash-conditions provides a special syntax for specifying conditions for the joined tables:
@@ -910,6 +965,47 @@ Using a class method is the preferred way to accept arguments for scopes. These
category.posts.1_week_before(time)
</ruby>
+h4. Working with scopes
+
+Where a relational object is required, the +scoped+ method may come in handy. This will return an +ActiveRecord::Relation+ object which can have further scoping applied to it afterwards. A place where this may come in handy is on associations
+
+<ruby>
+client = Client.find_by_first_name("Ryan")
+orders = client.orders.scoped
+</ruby>
+
+With this new +orders+ object, we are able to ascertain that this object can have more scopes applied to it. For instance, if we wanted to return orders only in the last 30 days at a later point.
+
+<ruby>
+orders.where("created_at > ?", 30.days.ago)
+</ruby>
+
+h4. Applying a default scope
+
+If we wish for a scope to be applied across all queries to the model we can use the +default_scope+ method within the model itself.
+
+<ruby>
+class Client < ActiveRecord::Base
+ default_scope where("removed_at IS NULL")
+end
+</ruby>
+
+When queries are executed on this model, the SQL query will now look something like this:
+
+<sql>
+SELECT * FROM clients WHERE removed_at IS NULL
+</sql>
+
+h4. Removing all scoping
+
+If we wish to remove scoping for any reason we can use the +unscoped+ method. This is especially useful if a +default_scope+ is specified in the model and should not be applied for this particular query.
+
+<ruby>
+Client.unscoped.all
+</ruby>
+
+This method removes all scoping and will do a normal query on the table.
+
h3. Dynamic Finders
For every field (also known as an attribute) you define in your table, Active Record provides a finder method. If you have a field called +first_name+ on your +Client+ model for example, you get +find_by_first_name+ and +find_all_by_first_name+ for free from Active Record. If you have a +locked+ field on the +Client+ model, you also get +find_by_locked+ and +find_all_by_locked+ methods.
@@ -1091,7 +1187,8 @@ For options, please see the parent section, "Calculations":#calculations.
h3. Changelog
-* December 23 2010: Add documentation for the +scope+ method. "Ryan Bigg":http://ryanbigg.com
+* June 26 2011: Added documentation for the +scoped+, +unscoped+ and +default+ methods. "Ryan Bigg":credits.html#radar
+* December 23 2010: Add documentation for the +scope+ method. "Ryan Bigg":credits.html#radar
* April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* February 3, 2010: Update to Rails 3 by "James Miller":credits.html#bensie
* February 7, 2009: Second version by "Pratik":credits.html#lifo
diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile
index 19bd4ad0f1..50ff1c9ff7 100644
--- a/railties/guides/source/active_record_validations_callbacks.textile
+++ b/railties/guides/source/active_record_validations_callbacks.textile
@@ -82,6 +82,7 @@ The following methods skip validations, and will save the object to the database
* +increment!+
* +increment_counter+
* +toggle!+
+* +touch+
* +update_all+
* +update_attribute+
* +update_column+
@@ -165,23 +166,23 @@ Each helper accepts an arbitrary number of attribute names, so with a single lin
All of them accept the +:on+ and +:message+ options, which define when the validation should be run and what message should be added to the +errors+ collection if it fails, respectively. The +:on+ option takes one of the values +:save+ (the default), +:create+ or +:update+. There is a default error message for each one of the validation helpers. These messages are used when the +:message+ option isn't specified. Let's take a look at each one of the available helpers.
-h4. +validates_acceptance_of+
+h4. +acceptance+
Validates that a checkbox on the user interface was checked when a form was submitted. This is typically used when the user needs to agree to your application's terms of service, confirm reading some text, or any similar concept. This validation is very specific to web applications and this 'acceptance' does not need to be recorded anywhere in your database (if you don't have a field for it, the helper will just create a virtual attribute).
<ruby>
class Person < ActiveRecord::Base
- validates_acceptance_of :terms_of_service
+ validates :terms_of_service, :acceptance => true
end
</ruby>
-The default error message for +validates_acceptance_of+ is "_must be accepted_".
+The default error message for this helper is "_must be accepted_".
-+validates_acceptance_of+ can receive an +:accept+ option, which determines the value that will be considered acceptance. It defaults to "1", but you can change this.
+It can receive an +:accept+ option, which determines the value that will be considered acceptance. It defaults to "1" and can be easily changed.
<ruby>
class Person < ActiveRecord::Base
- validates_acceptance_of :terms_of_service, :accept => 'yes'
+ validates :terms_of_service, :acceptance => { :accept => 'yes' }
end
</ruby>
@@ -202,13 +203,13 @@ CAUTION: Don't use +validates_associated+ on both ends of your associations. The
The default error message for +validates_associated+ is "_is invalid_". Note that each associated object will contain its own +errors+ collection; errors do not bubble up to the calling model.
-h4. +validates_confirmation_of+
+h4. +confirmation+
You should use this helper when you have two text fields that should receive exactly the same content. For example, you may want to confirm an email address or a password. This validation creates a virtual attribute whose name is the name of the field that has to be confirmed with "_confirmation" appended.
<ruby>
class Person < ActiveRecord::Base
- validates_confirmation_of :email
+ validates :email, :confirmation => true
end
</ruby>
@@ -219,70 +220,70 @@ In your view template you could use something like
<%= text_field :person, :email_confirmation %>
</erb>
-This check is performed only if +email_confirmation+ is not +nil+. To require confirmation, make sure to add a presence check for the confirmation attribute (we'll take a look at +validates_presence_of+ later on this guide):
+This check is performed only if +email_confirmation+ is not +nil+. To require confirmation, make sure to add a presence check for the confirmation attribute (we'll take a look at +presence+ later on this guide):
<ruby>
class Person < ActiveRecord::Base
- validates_confirmation_of :email
- validates_presence_of :email_confirmation
+ validates :email, :confirmation => true
+ validates :email_confirmation, :presence => true
end
</ruby>
-The default error message for +validates_confirmation_of+ is "_doesn't match confirmation_".
+The default error message for this helper is "_doesn't match confirmation_".
-h4. +validates_exclusion_of+
+h4. +exclusion+
This helper validates that the attributes' values are not included in a given set. In fact, this set can be any enumerable object.
<ruby>
class Account < ActiveRecord::Base
- validates_exclusion_of :subdomain, :in => %w(www us ca jp),
- :message => "Subdomain %{value} is reserved."
+ validates :subdomain, :exclusion => { :in => %w(www us ca jp),
+ :message => "Subdomain %{value} is reserved." }
end
</ruby>
-The +validates_exclusion_of+ helper has an option +:in+ that receives the set of values that will not be accepted for the validated attributes. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. This example uses the +:message+ option to show how you can include the attribute's value.
+The +exclusion+ helper has an option +:in+ that receives the set of values that will not be accepted for the validated attributes. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. This example uses the +:message+ option to show how you can include the attribute's value.
-The default error message for +validates_exclusion_of+ is "_is reserved_".
+The default error message is "_is reserved_".
-h4. +validates_format_of+
+h4. +format+
This helper validates the attributes' values by testing whether they match a given regular expression, which is specified using the +:with+ option.
<ruby>
class Product < ActiveRecord::Base
- validates_format_of :legacy_code, :with => /\A[a-zA-Z]+\z/,
- :message => "Only letters allowed"
+ validates :legacy_code, :format => { :with => /\A[a-zA-Z]+\z/,
+ :message => "Only letters allowed" }
end
</ruby>
-The default error message for +validates_format_of+ is "_is invalid_".
+The default error message is "_is invalid_".
-h4. +validates_inclusion_of+
+h4. +inclusion+
This helper validates that the attributes' values are included in a given set. In fact, this set can be any enumerable object.
<ruby>
class Coffee < ActiveRecord::Base
- validates_inclusion_of :size, :in => %w(small medium large),
- :message => "%{value} is not a valid size"
+ validates :size, :inclusion => { :in => %w(small medium large),
+ :message => "%{value} is not a valid size" }
end
</ruby>
-The +validates_inclusion_of+ helper has an option +:in+ that receives the set of values that will be accepted. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. The previous example uses the +:message+ option to show how you can include the attribute's value.
+The +inclusion+ helper has an option +:in+ that receives the set of values that will be accepted. The +:in+ option has an alias called +:within+ that you can use for the same purpose, if you'd like to. The previous example uses the +:message+ option to show how you can include the attribute's value.
-The default error message for +validates_inclusion_of+ is "_is not included in the list_".
+The default error message for this helper is "_is not included in the list_".
-h4. +validates_length_of+
+h4. +length+
This helper validates the length of the attributes' values. It provides a variety of options, so you can specify length constraints in different ways:
<ruby>
class Person < ActiveRecord::Base
- validates_length_of :name, :minimum => 2
- validates_length_of :bio, :maximum => 500
- validates_length_of :password, :in => 6..20
- validates_length_of :registration_number, :is => 6
+ validates :name, :length => { :minimum => 2 }
+ validates :bio, :length => { :maximum => 500 }
+ validates :password, :length => { :in => 6..20 }
+ validates :registration_number, :length => { :is => 6 }
end
</ruby>
@@ -297,8 +298,8 @@ The default error messages depend on the type of length validation being perform
<ruby>
class Person < ActiveRecord::Base
- validates_length_of :bio, :maximum => 1000,
- :too_long => "%{count} characters is the maximum allowed"
+ validates :bio, :length => { :maximum => 1000,
+ :too_long => "%{count} characters is the maximum allowed" }
end
</ruby>
@@ -306,20 +307,21 @@ This helper counts characters by default, but you can split the value in a diffe
<ruby>
class Essay < ActiveRecord::Base
- validates_length_of :content,
+ validates :content, :length => {
:minimum => 300,
:maximum => 400,
:tokenizer => lambda { |str| str.scan(/\w+/) },
:too_short => "must have at least %{count} words",
:too_long => "must have at most %{count} words"
+ }
end
</ruby>
-Note that the default error messages are plural (e.g., "is too short (minimum is %{count} characters)"). For this reason, when +:minimum+ is 1 you should provide a personalized message or use +validates_presence_of+ instead. When +:in+ or +:within+ have a lower limit of 1, you should either provide a personalized message or call +validates_presence_of+ prior to +validates_length_of+.
+Note that the default error messages are plural (e.g., "is too short (minimum is %{count} characters)"). For this reason, when +:minimum+ is 1 you should provide a personalized message or use +validates_presence_of+ instead. When +:in+ or +:within+ have a lower limit of 1, you should either provide a personalized message or call +presence+ prior to +length+.
-The +validates_size_of+ helper is an alias for +validates_length_of+.
+The +size+ helper is an alias for +length+.
-h4. +validates_numericality_of+
+h4. +numericality+
This helper validates that your attributes have only numeric values. By default, it will match an optional sign followed by an integral or floating point number. To specify that only integral numbers are allowed set +:only_integer+ to true.
@@ -335,12 +337,12 @@ WARNING. Note that the regular expression above allows a trailing newline charac
<ruby>
class Player < ActiveRecord::Base
- validates_numericality_of :points
- validates_numericality_of :games_played, :only_integer => true
+ validates :points, :numericality => true
+ validates :games_played, :numericality => { :only_integer => true }
end
</ruby>
-Besides +:only_integer+, the +validates_numericality_of+ helper also accepts the following options to add constraints to acceptable values:
+Besides +:only_integer+, this helper also accepts the following options to add constraints to acceptable values:
* +:greater_than+ - Specifies the value must be greater than the supplied value. The default error message for this option is "_must be greater than %{count}_".
* +:greater_than_or_equal_to+ - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "_must be greater than or equal to %{count}_".
@@ -350,9 +352,9 @@ Besides +:only_integer+, the +validates_numericality_of+ helper also accepts the
* +:odd+ - Specifies the value must be an odd number if set to true. The default error message for this option is "_must be odd_".
* +:even+ - Specifies the value must be an even number if set to true. The default error message for this option is "_must be even_".
-The default error message for +validates_numericality_of+ is "_is not a number_".
+The default error message is "_is not a number_".
-h4. +validates_presence_of+
+h4. +presence+
This helper validates that the specified attributes are not empty. It uses the +blank?+ method to check if the value is either +nil+ or a blank string, that is, a string that is either empty or consists of whitespace.
@@ -367,21 +369,21 @@ If you want to be sure that an association is present, you'll need to test wheth
<ruby>
class LineItem < ActiveRecord::Base
belongs_to :order
- validates_presence_of :order_id
+ validates :order_id, :presence => true
end
</ruby>
-Since +false.blank?+ is true, if you want to validate the presence of a boolean field you should use +validates_inclusion_of :field_name, :in => [true, false]+.
+Since +false.blank?+ is true, if you want to validate the presence of a boolean field you should use <tt>validates :field_name, :inclusion => { :in => [true, false] }</tt>.
-The default error message for +validates_presence_of+ is "_can't be empty_".
+The default error message is "_can't be empty_".
-h4. +validates_uniqueness_of+
+h4. +uniqueness+
This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint in the database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create a unique index in your database.
<ruby>
class Account < ActiveRecord::Base
- validates_uniqueness_of :email
+ validates :email, :uniqueness => true
end
</ruby>
@@ -391,8 +393,8 @@ There is a +:scope+ option that you can use to specify other attributes that are
<ruby>
class Holiday < ActiveRecord::Base
- validates_uniqueness_of :name, :scope => :year,
- :message => "should happen once per year"
+ validates :name, :uniqueness => { :scope => :year,
+ :message => "should happen once per year" }
end
</ruby>
@@ -400,13 +402,13 @@ There is also a +:case_sensitive+ option that you can use to define whether the
<ruby>
class Person < ActiveRecord::Base
- validates_uniqueness_of :name, :case_sensitive => false
+ validates :name, :uniqueness => { :case_sensitive => false }
end
</ruby>
WARNING. Note that some databases are configured to perform case-insensitive searches anyway.
-The default error message for +validates_uniqueness_of+ is "_has already been taken_".
+The default error message is "_has already been taken_".
h4. +validates_with+
@@ -428,7 +430,7 @@ end
The +validates_with+ helper takes a class, or a list of classes to use for validation. There is no default error message for +validates_with+. You must manually add errors to the record's errors collection in the validator class.
-To implement the validate method, you must have an +record+ parameter defined, which is the record to be validated.
+To implement the validate method, you must have a +record+ parameter defined, which is the record to be validated.
Like all other validations, +validates_with+ takes the +:if+, +:unless+ and +:on+ options. If you pass any other options, it will send those options to the validator class as +options+:
@@ -470,8 +472,8 @@ The +:allow_nil+ option skips the validation when the value being validated is +
<ruby>
class Coffee < ActiveRecord::Base
- validates_inclusion_of :size, :in => %w(small medium large),
- :message => "%{value} is not a valid size", :allow_nil => true
+ validates :size, :inclusion => { :in => %w(small medium large),
+ :message => "%{value} is not a valid size" }, :allow_nil => true
end
</ruby>
@@ -483,10 +485,10 @@ The +:allow_blank+ option is similar to the +:allow_nil+ option. This option wil
<ruby>
class Topic < ActiveRecord::Base
- validates_length_of :title, :is => 5, :allow_blank => true
+ validates :title, :length => { :is => 5 }, :allow_blank => true
end
-Topic.create("title" => "").valid? # => true
+Topic.create("title" => "").valid? # => true
Topic.create("title" => nil).valid? # => true
</ruby>
@@ -503,10 +505,10 @@ The +:on+ option lets you specify when the validation should happen. The default
<ruby>
class Person < ActiveRecord::Base
# it will be possible to update email with a duplicated value
- validates_uniqueness_of :email, :on => :create
+ validates :email, :uniqueness => true, :on => :create
# it will be possible to create the record with a non-numerical age
- validates_numericality_of :age, :on => :update
+ validates :age, :numericality => true, :on => :update
# the default (validates on both create and update)
validates :name, :presence => true, :on => :save
@@ -523,7 +525,7 @@ You can associate the +:if+ and +:unless+ options with a symbol corresponding to
<ruby>
class Order < ActiveRecord::Base
- validates_presence_of :card_number, :if => :paid_with_card?
+ validates :card_number, :presence => true, :if => :paid_with_card?
def paid_with_card?
payment_type == "card"
@@ -537,7 +539,7 @@ You can also use a string that will be evaluated using +eval+ and needs to conta
<ruby>
class Person < ActiveRecord::Base
- validates_presence_of :surname, :if => "name.nil?"
+ validates :surname, :presence => true, :if => "name.nil?"
end
</ruby>
@@ -547,7 +549,7 @@ Finally, it's possible to associate +:if+ and +:unless+ with a +Proc+ object whi
<ruby>
class Account < ActiveRecord::Base
- validates_confirmation_of :password,
+ validates :password, :confirmation => true,
:unless => Proc.new { |a| a.password.blank? }
end
</ruby>
@@ -559,8 +561,8 @@ Sometimes it is useful to have multiple validations use one condition, it can be
<ruby>
class User < ActiveRecord::Base
with_options :if => :is_admin? do |admin|
- admin.validates_length_of :password, :minimum => 10
- admin.validates_presence_of :email
+ admin.validates :password, :length => { :minimum => 10 }
+ admin.validates :email, :presence => true
end
end
</ruby>
@@ -597,7 +599,7 @@ You can even create your own validation helpers and reuse them in several differ
<ruby>
ActiveRecord::Base.class_eval do
def self.validates_as_choice(attr_name, n, options={})
- validates_inclusion_of attr_name, {:in => 1..n}.merge(options)
+ validates attr_name, :inclusion => { {:in => 1..n}.merge(options) }
end
end
</ruby>
@@ -622,8 +624,7 @@ Returns an OrderedHash with all errors. Each key is the attribute name and the v
<ruby>
class Person < ActiveRecord::Base
- validates :name, :presence => true
- validates_length_of :name, :minimum => 3
+ validates :name, :presence => true, :length => { :minimum => 3 }
end
person = Person.new
@@ -642,8 +643,7 @@ h4(#working_with_validation_errors-errors-2). +errors[]+
<ruby>
class Person < ActiveRecord::Base
- validates :name, :presence => true
- validates_length_of :name, :minimum => 3
+ validates :name, :presence => true, :length => { :minimum => 3 }
end
person = Person.new(:name => "John Doe")
@@ -718,8 +718,7 @@ The +clear+ method is used when you intentionally want to clear all the messages
<ruby>
class Person < ActiveRecord::Base
- validates :name, :presence => true
- validates_length_of :name, :minimum => 3
+ validates :name, :presence => true, :length => { :minimum => 3 }
end
person = Person.new
@@ -742,9 +741,7 @@ The +size+ method returns the total number of error messages for the object.
<ruby>
class Person < ActiveRecord::Base
- validates :name, :presence => true
- validates_length_of :name, :minimum => 3
- validates_presence_of :email
+ validates :name, :presence => true, :length => { :minimum => 3 }
end
person = Person.new
@@ -765,13 +762,14 @@ h4. Installing as a plugin
$ rails plugin install git://github.com/joelmoss/dynamic_form.git
</shell>
-h4 Installing as a Gem
-Add this line on your Gemfile:
+h4. Installing as a Gem
+
+Add this line in your Gemfile:
<ruby>
gem "dynamic_form"
</ruby>
-Now you will have access to these two methods in your view templates:
+Now you will have access to these two methods in your view templates.
h4. +error_messages+ and +error_messages_for+
@@ -779,8 +777,8 @@ When creating a form with the +form_for+ helper, you can use the +error_messages
<ruby>
class Product < ActiveRecord::Base
- validates_presence_of :description, :value
- validates_numericality_of :value, :allow_nil => true
+ validates :description, :value, :presence => true
+ validates :value, :numericality => true, :allow_nil => true
end
</ruby>
@@ -878,7 +876,7 @@ In order to use the available callbacks, you need to register them. You can do t
<ruby>
class User < ActiveRecord::Base
- validates_presence_of :login, :email
+ validates :login, :email, :presence => true
before_validation :ensure_login_has_a_value
@@ -895,7 +893,7 @@ The macro-style class methods can also receive a block. Consider using this styl
<ruby>
class User < ActiveRecord::Base
- validates_presence_of :login, :email
+ validates :login, :email, :presence => true
before_create do |user|
user.name = user.login.capitalize if user.name.blank?
@@ -914,20 +912,20 @@ h4. Creating an Object
* +before_validation+
* +after_validation+
* +before_save+
-* +after_save+
* +before_create+
* +around_create+
* +after_create+
+* +after_save+
h4. Updating an Object
* +before_validation+
* +after_validation+
* +before_save+
-* +after_save+
* +before_update+
* +around_update+
* +after_update+
+* +after_save+
h4. Destroying an Object
@@ -1010,6 +1008,7 @@ Just as with validations, it's also possible to skip callbacks. These methods sh
* +increment+
* +increment_counter+
* +toggle+
+* +touch+
* +update_column+
* +update_all+
* +update_counters+
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index 66869b4eeb..a0ed85cf01 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -436,20 +436,6 @@ end
NOTE: Defined in +active_support/core_ext/kernel/reporting.rb+.
-h4. +require_library_or_gem+
-
-The convenience method +require_library_or_gem+ tries to load its argument with a regular +require+ first. If it fails loads +rubygems+ and tries again.
-
-If the first attempt is a failure and +rubygems+ can't be loaded the method raises +LoadError+. A +LoadError+ is also raised if +rubygems+ is available but the argument is not loadable as a gem.
-
-For example, that's the way the MySQL adapter loads the MySQL library:
-
-<ruby>
-require_library_or_gem('mysql')
-</ruby>
-
-NOTE: Defined in +active_support/core_ext/kernel/requires.rb+.
-
h4. +in?+
The predicate +in?+ tests if an object is included in another object. An +ArgumentError+ exception will be raised if the argument passed does not respond to +include?+.
@@ -882,7 +868,7 @@ The macro accepts several methods:
delegate :name, :age, :address, :twitter, :to => :profile
</ruby>
-When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such a expression is evaluated in the context of the receiver:
+When interpolated into a string, the +:to+ option should become an expression that evaluates to the object the method is delegated to. Typically a string or symbol. Such an expression is evaluated in the context of the receiver:
<ruby>
# delegates to the Rails constant
@@ -961,7 +947,7 @@ h4. Class Attributes
h5. +class_attribute+
-The method +class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy:
+The method +class_attribute+ declares one or more inheritable class attributes that can be overridden at any level down the hierarchy.
<ruby>
class A
@@ -997,7 +983,7 @@ self.default_params = {
}.freeze
</ruby>
-They can be also accessed and overridden at the instance level:
+They can be also accessed and overridden at the instance level.
<ruby>
A.x = 1
@@ -1010,7 +996,7 @@ a1.x # => 1, comes from A
a2.x # => 2, overridden in a2
</ruby>
-The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to false, as in
+The generation of the writer instance method can be prevented by setting the option +:instance_writer+ to +false+.
<ruby>
module ActiveRecord
@@ -1023,8 +1009,20 @@ end
A model may find that option useful as a way to prevent mass-assignment from setting the attribute.
+The generation of the reader instance method can be prevented by setting the option +:instance_reader+ to +false+.
+
+<ruby>
+class A
+ class_attribute :x, :instance_reader => false
+end
+
+A.x = 1 # NoMethodError
+</ruby>
+
For convenience +class_attribute+ also defines an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called +x?+.
+When +:instance_reader+ is +false+, the instance predicate returns a +NoMethodError+ just like the reader method.
+
NOTE: Defined in +active_support/core_ext/class/attribute.rb+
h5. +cattr_reader+, +cattr_writer+, and +cattr_accessor+
@@ -1050,18 +1048,24 @@ module ActionView
end
</ruby>
-we can access +field_error_proc+ in views. The generation of the writer instance method can be prevented by setting +:instance_writer+ to +false+ (not any false value, but exactly +false+):
+we can access +field_error_proc+ in views.
+
+The generation of the reader instance method can be prevented by setting +:instance_reader+ to +false+ and the generation of the writer instance method can be prevented by setting +:instance_writer+ to +false+. Generation of both methods can be prevented by setting +:instance_accessor+ to +false+. In all cases, the value must be exactly +false+ and not any false value.
<ruby>
-module ActiveRecord
- class Base
- # No pluralize_table_names= instance writer is generated.
- cattr_accessor :pluralize_table_names, :instance_writer => false
+module A
+ class B
+ # No first_name instance reader is generated.
+ cattr_accessor :first_name, :instance_reader => false
+ # No last_name= instance writer is generated.
+ cattr_accessor :last_name, :instance_writer => false
+ # No surname instance reader or surname= writer is generated.
+ cattr_accessor :surname, :instance_accessor => false
end
end
</ruby>
-A model may find that option useful as a way to prevent mass-assignment from setting the attribute.
+A model may find it useful to set +:instance_accessor+ to +false+ as a way to prevent mass-assignment from setting the attribute.
NOTE: Defined in +active_support/core_ext/class/attribute_accessors.rb+.
@@ -1160,8 +1164,12 @@ h3. Extensions to +String+
h4. Output Safety
+h5. Motivation
+
Inserting data into HTML templates needs extra care. For example you can't just interpolate +@review.title+ verbatim into an HTML page. On one hand if the review title is "Flanagan & Matz rules!" the output won't be well-formed because an ampersand has to be escaped as "&amp;amp;". On the other hand, depending on the application that may be a big security hole because users can inject malicious HTML setting a hand-crafted review title. Check out the "section about cross-site scripting in the Security guide":security.html#cross-site-scripting-xss for further information about the risks.
+h5. Safe Strings
+
Active Support has the concept of <i>(html) safe</i> strings since Rails 3. A safe string is one that is marked as being insertable into HTML as is. It is trusted, no matter whether it has been escaped or not.
Strings are considered to be <i>unsafe</i> by default:
@@ -1187,8 +1195,6 @@ s # => "<script>...</script>"
It is your responsibility to ensure calling +html_safe+ on a particular string is fine.
-NOTE: For performance reasons safe strings are implemented in a way that cannot offer an in-place +html_safe!+ variant.
-
If you append onto a safe string, either in-place with +concat+/<tt><<</tt>, or with <tt>+</tt>, the result is a safe string. Unsafe arguments are escaped:
<ruby>
@@ -1229,6 +1235,22 @@ end
NOTE: Defined in +active_support/core_ext/string/output_safety.rb+.
+h5. Transformation
+
+As a rule of thumb, except perhaps for concatenation as explained above, any method that may change a string gives you an unsafe string. These are +donwcase+, +gsub+, +strip+, +chomp+, +underscore+, etc.
+
+In the case of in-place transformations like +gsub!+ the receiver itself becomes unsafe.
+
+INFO: The safety bit is lost always, no matter whether the transformation actually changed something.
+
+h5. Conversion and Coercion
+
+Calling +to_s+ on a safe string returns a safe string, but coercion with +to_str+ returns an unsafe string.
+
+h5. Copying
+
+Calling +dup+ or +clone+ on safe strings yields safe strings.
+
h4. +squish+
The method +squish+ strips leading and trailing whitespace, and substitutes runs of whitespace with a single space each:
@@ -1474,7 +1496,15 @@ end
That may be handy to compute method names in a language that follows that convention, for example JavaScript.
-INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>.
+INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>. To support cases such as this, Active Support allows you to specify acronyms in +config/initializers/inflections.rb+:
+
+<ruby>
+ActiveSupport::Inflector.inflections do |inflect|
+ inflect.acronym 'SSL'
+end
+
+"SSLError".underscore.camelize #=> "SSLError"
+</ruby>
+camelize+ is aliased to +camelcase+.
@@ -2219,8 +2249,8 @@ The method +Array.wrap+ wraps its argument in an array unless it is already an a
Specifically:
* If the argument is +nil+ an empty list is returned.
-* Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
-* Otherwise, returns an array with the argument as its single element.
+* Otherwise, if the argument responds to +to_ary+ it is invoked, and if the value of +to_ary+ is not +nil+, it is returned.
+* Otherwise, an array with the argument as its single element is returned.
<ruby>
Array.wrap(nil) # => []
@@ -2296,7 +2326,7 @@ NOTE: Defined in +active_support/core_ext/array/grouping.rb+.
h5. +in_groups(number, fill_with = nil)+
-The method +in_groups+ splits an array into a certain number of groups. The method returns and array with the groups:
+The method +in_groups+ splits an array into a certain number of groups. The method returns an array with the groups:
<ruby>
%w(1 2 3 4 5 6 7).in_groups(3)
@@ -2728,7 +2758,7 @@ Active Support extends the method +Range#step+ so that it can be invoked without
(1..10).step(2) # => [1, 3, 5, 7, 9]
</ruby>
-As the example shows, in that case the method returns and array with the corresponding elements.
+As the example shows, in that case the method returns an array with the corresponding elements.
NOTE: Defined in +active_support/core_ext/range/blockless_step.rb+.
@@ -3038,7 +3068,7 @@ Date.new(2010, 1, 31).change(:month => 2)
h5(#date-durations). Durations
-Durations can be added and substracted to dates:
+Durations can be added to and subtracted from dates:
<ruby>
d = Date.current
@@ -3246,7 +3276,7 @@ DateTime.current.change(:month => 2, :day => 30)
h5(#datetime-durations). Durations
-Durations can be added and substracted to datetimes:
+Durations can be added to and subtracted from datetimes:
<ruby>
now = DateTime.current
@@ -3330,6 +3360,32 @@ Active Support defines +Time.current+ to be today in the current time zone. That
When making Time comparisons using methods which honor the user time zone, make sure to use +Time.current+ and not +Time.now+. There are cases where the user time zone might be in the future compared to the system time zone, which +Time.today+ uses by default. This means +Time.now+ may equal +Time.yesterday+.
+h5. +all_day+, +all_week+, +all_month+, +all_quarter+ and +all_year+
+
+The method +all_day+ returns a range representing the whole day of the current time.
+
+<ruby>
+now = Time.current
+# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
+now.all_day
+# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Mon, 09 Aug 2010 23:59:59 UTC +00:00
+</ruby>
+
+Analogously, +all_week+, +all_month+, +all_quarter+ and +all_year+ all serve the purpose of generating time ranges.
+
+<ruby>
+now = Time.current
+# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
+now.all_week
+# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Sun, 15 Aug 2010 23:59:59 UTC +00:00
+now.all_month
+# => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +00:00
+now.all_quarter
+# => Thu, 01 Jul 2010 00:00:00 UTC +00:00..Thu, 30 Sep 2010 23:59:59 UTC +00:00
+now.all_year
+# => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00
+</ruby>
+
h4. Time Constructors
Active Support defines +Time.current+ to be +Time.zone.now+ if there's a user time zone defined, with fallback to +Time.now+:
@@ -3367,7 +3423,7 @@ If the time to be constructed lies beyond the range supported by +Time+ in the r
h5(#time-durations). Durations
-Durations can be added and substracted to time objects:
+Durations can be added to and subtracted from time objects:
<ruby>
now = Time.current
diff --git a/railties/guides/source/ajax_on_rails.textile b/railties/guides/source/ajax_on_rails.textile
index 1566c23414..8b72e20c33 100644
--- a/railties/guides/source/ajax_on_rails.textile
+++ b/railties/guides/source/ajax_on_rails.textile
@@ -72,7 +72,7 @@ link_to_remote "Add to cart",
If the server returns 200, the output of the above example is equivalent to our first, simple one. However, in case of error, the element with the DOM id +error+ is updated rather than the +cart+ element.
-** *position* By default (i.e. when not specifying this option, like in the examples before) the repsonse is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities:
+** *position* By default (i.e. when not specifying this option, like in the examples before) the response is injected into the element with the specified DOM id, replacing the original content of the element (if there was any). You might want to alter this behavior by keeping the original content - the only question is where to place the new content? This can specified by the +position+ parameter, with four possibilities:
*** +:before+ Inserts the response text just before the target element. More precisely, it creates a text node from the response and inserts it as the left sibling of the target element.
*** +:after+ Similar behavior to +:before+, but in this case the response is inserted after the target element.
*** +:top+ Inserts the text into the target element, before it's original content. If the target element was empty, this is equivalent with not specifying +:position+ at all.
diff --git a/railties/guides/source/api_documentation_guidelines.textile b/railties/guides/source/api_documentation_guidelines.textile
index e22ffa4c04..50e86e05a8 100644
--- a/railties/guides/source/api_documentation_guidelines.textile
+++ b/railties/guides/source/api_documentation_guidelines.textile
@@ -33,12 +33,16 @@ Spell names correctly: Arel, Test::Unit, RSpec, HTML, MySQL, JavaScript, ERB. Wh
Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite database".
+h3. English
+
+Please use American English (_color_, _center_, _modularize_, etc.). See "a list of American and British English spelling differences here":http://en.wikipedia.org/wiki/American_and_British_English_spelling_differences.
+
h3. Example Code
Choose meaningful examples that depict and cover the basics as well as interesting points or gotchas.
-Use two spaces to indent chunks of code.—that is two spaces with respect to the left margin; the examples
-themselves should use "Rails code conventions":http://rails.lighthouseapp.com/projects/8994/source-style.
+Use two spaces to indent chunks of code--that is two spaces with respect to the left margin; the examples
+themselves should use "Rails coding conventions":contributing_to_ruby_on_rails.html#follow-the-coding-conventions.
Short docs do not need an explicit "Examples" label to introduce snippets, they just follow paragraphs:
diff --git a/railties/guides/source/asset_pipeline.textile b/railties/guides/source/asset_pipeline.textile
new file mode 100644
index 0000000000..563c1c79ae
--- /dev/null
+++ b/railties/guides/source/asset_pipeline.textile
@@ -0,0 +1,335 @@
+h2. Asset Pipeline
+
+This guide will cover the ideology of the asset pipeline introduced in Rails 3.1.
+By referring to this guide you will be able to:
+
+* Understand what the asset pipeline is and what it does
+* Properly organize your application assets
+* Understand the benefits of the asset pipeline
+* Adding a pre-processor to the pipeline
+* Package assets with a gem
+
+endprologue.
+
+h3. What Is The Asset Pipeline?
+
+The asset pipeline provides a framework to concatenate and minify or compress Javascript and CSS assets. It also adds the ability to write these assets in other languages such as CoffeeScript, SCSS and ERB.
+
+Prior to Rails 3.1 these features were added through third-party Ruby libraries such as Jammit and Sprockets. Rails 3.1 includes the +sprockets-rails+ gem, which depends on the +sprockets+ gem, by default.
+
+By having this as a core feature of Rails, all developers can benefit from the power of having their assets pre-processed, compressed and minified by one central library, Sprockets. This is part of Rails' "Fast by default" strategy as outlined by DHH in his 2011 keynote at Railsconf.
+
+In new Rails 3.1 application the asset pipeline is enable by default. It can be disabled in +application.rb+ by putting this line inside the +Application+ class definition:
+
+<plain>
+ config.assets.enabled = false
+</plain>
+
+It is recommended that you use the defaults for all new apps.
+
+
+h4. Main Features
+
+The first is to concatenate of assets. This is important in a production environment to reduce the number of requests that a client browser has to make to render a web page. While Rails already has a feature to concatenate these types of asset--by placing +:cache => true+ at the end of tags such as +javascript_include_tag+ and +stylesheet_link_tag+--, many people do not use it.
+
+The default behavior in Rails 3.1 and onward is to concatenate all files into one master file each for JS and CSS, however you can separate files or groups of files if required (see below). In production an MD5 fingerprint is inserted into each filename.
+
+The second feature of the pipeline is to minify or compress. For CSS this usually involves removing whitespace and comments. For Javascript more complex processes can be applied.
+
+You can choose from a set of built in options or specify your own.
+
+The third feature is the ability to code these assets using another language, or language extension. These include SCSS or Sass for CSS, CoffeeScript for Javascript, and ERB for both.
+
+h4. What is fingerprinting and why should I care?
+
+Fingerprinting is a technique where the filenames of content that is static or infrequently updated is altered to be unique to the content contained in the file.
+
+When a filename is unique and based on its content, http headers can be set to encourage caches everywhere (at ISPs, in browsers) to keep there own copy of the content. When the content is updated, the fingerprint will change and the remote clients will request the new file. This is generally known as _cachebusting_.
+
+The most effective technique is to insert a hash of the content into the name, usually at the end. For example a CSS file +global.css+ is hashed and the filename is updated to incorporate the hash.
+
+<plain>
+global.css => global-908e25f4bf641868d8683022a5b62f54.css
+</plain>
+
+This is the strategy adopted by the Rails asset pipeline.
+
+Rails old strategy was to append a query string to every asset linked with a built-in helper. In the source the generated code looked like this:
+
+<plain>
+/stylesheets/global.css?1309495796
+</plain>
+
+This has several disadvantages:
+
+1. Not all caches will cache content with a query string
+
+"Steve Souders recommends":http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/, "...avoiding a querystring for cacheable resources". He found that in these case 5-20% of requests will not be cached.
+
+2. The filename can change between nodes in multi-server environments.
+
+The query string in Rails is based on the files mtime (mtime is the file modification time). When assets are deployed to a cluster, there is no guarantee that the timestamps will be the same, resulting in different values being used depending on which server handles the request.
+
+The other problems is that when static assets are deployed with each new release of code, the mtime of *all* these files changes, forcing all remote clients to fetch them again, even when the content of those assets has not changed.
+
+Fingerprinting avoids all these problems be ensuring filenames are consistent based on the content.
+
+More reading:
+
+* "Optimize caching":http://code.google.com/speed/page-speed/docs/caching.html
+* "Revving Filenames: don’t use querystring":http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/
+
+
+h3. How to Use the Asset Pipeline
+
+In previous versions of Rails, all assets were located in subdirectories of +public+ such as +images+, +javascripts+ and +stylesheets+. With the asset pipeline, the preferred location for these assets is now the +app/assets+ directory. Files in this directory will be served by the Sprockets middleware included in the sprockets gem.
+
+This is not to say that assets can (or should) no longer be placed in +public+. They still can be and will be served as static files by the application or web server. You would only use +app/assets+ if you wish your files to undergo some pre-processing before they are served.
+
+When a scaffold or controller is generated for the application, Rails will also generate a JavaScript file (or CoffeeScript if the +coffee-script+ gem is in the +Gemfile+) and a Cascading Style Sheet file (or SCSS if +sass-rails+ is in the +Gemfile+) file for that controller.
+
+For example, if a +ProjectsController+ is generated, there will be a new file at +app/assets/javascripts/projects.js.coffee+ and another at +app/assets/stylesheets/projects.css.scss+. You should put any JavaScript or CSS unique to a controller inside their respective asset files, as these files can then be loaded just for these controllers with lines such as +<%= javascript_include_tag params[:controller] %>+ or +<%= stylesheet_link_tag params[:controller] %>+.
+
+h4. Asset Organization
+
+Assets can be placed inside an application in one of three locations: +app/assets+, +lib/assets+ or +vendor/assets+.
+
++app/assets+ is for assets that are owned by the application, such as custom images, JavaScript files or stylesheets.
+
++lib/assets+ is for your own libraries' code that doesn't really fit into the scope of the application or those libraries which are shared across applications.
+
++vendor/assets+ is for assets that are owned by outside entities, such as code for JavaScript plugins.
+
+All subdirectories that exists within these three locations will be added to the search path for Sprockets (visible by calling +Rails.application.config.assets.paths+ in a console). When an asset is requested, these paths will be looked through to see if they contain an asset matching the name specified. Once an asset has been found, it's processed by Sprockets and served.
+
+h4. Coding links to Assets
+
+To access assets, we can use the same tags that we are generally familiar with:
+
+<erb>
+ <%= image_tag "rails.png" %>
+</erb>
+
+Providing that assets are enabled within our application (+config.assets.enabled+ in the current environment's file is not set to +false+), this file will be served by Sprockets unless a file at +public/assets/rails.png+ exists, in which case that file will be served. Alternatively, a file with an MD5 hash after its name such as +public/assets/rails-af27b6a414e6da00003503148be9b409.png+ will also be picked up by Sprockets. How these hashes are generated is covered in the "Production Assets":#production_assets section later on in this guide.
+
+Otherwise, Sprockets will look through the available paths until it finds a file that matches the name and then will serve it, first looking in the application's assets directories and then falling back to the various engines of the application.
+
+Sprockets does not add any new methods to require your assets, we still use the familiar +javascript_include_tag+ and +stylesheet_link_tag+.
+
+<erb>
+ <%= stylesheet_link_tag "application" %>
+ <%= javascript_include_tag "application" %>
+</erb>
+
+These helpers (when the pipeline is on) are providing links to the compiled manifest with the specified name (or names).
+
+h4. Manifest Files and Directives
+
+Sprockets uses manifest files to determine which assets to include and serve. These manifest files contain _directives_ - instructions that tell Sprockets which files to require in order to build a single CSS or JavaScript file. With these directives, Sprockets will load the files specified, process them if necessary, concatenate them into one single file and then compress them (if +Rails.application.config.assets.compress+ is set to +true+). By serving one file rather than many, a page's load time is greatly reduced.
+
+For example, in the default Rails application there's a +app/assets/javascripts/application.js+ file which contains the following lines:
+
+<plain>
+//= require jquery
+//= require jquery_ujs
+//= require_tree .
+</plain>
+
+In JavaScript files, directives begin with +//=+. In this case, the following file is using the +require+ directive and the +require_tree+ directive. The +require+ directive tells Sprockets that we would like to require a file called +jquery.js+ that is available somewhere in the search path for Sprockets. By default, this is located inside the +vendor/assets/javascripts+ directory contained within the +jquery-rails+ gem. An identical event takes place for the +jquery_ujs+ require
+
+The +require_tree .+ directive tells Sprockets to include _all_ JavaScript files in this directory into the output. Only a path relative to the file can be specified.
+
+There's also a default +app/assets/stylesheets/application.css+ file which contains these lines:
+
+<plain>
+/* ...
+*= require_self
+*= require_tree .
+*/
+</plain>
+
+The directives that work in the JavaScript files will also work in stylesheets, obviously including stylesheets rather than JavaScript files. The +require_tree+ directive here works the same way as the JavaScript one, requiring all stylesheets from the current directory.
+
+In this example +require_self+ is used. This will put the CSS contained within the file (if any) at the top of any other CSS in this file unless +require_self+ is specified after another +require+ directive.
+
+You can have as many manifest files as you need. For example the +admin.css+ and +admin.js+ manifest could contain the JS and CSS files that are used for the admin section of an application.
+
+For some assets (like CSS) the compiled order is important. You can specify individual files and they will be compiled in the order specified:
+
+<plain>
+/* ...
+*= require reset
+*= require layout
+*= require chrome
+*/
+</plain>
+
+
+h4. Preprocessing
+
+The file extensions used on an asset will determine what preprocssing will be applied. When a controller or a scaffold is generated with the default Rails gemset, a CoffeeScript file and a SCSS file will be generated in place of a regular JavaScript and CSS file. The example used before was a controller called "projects", which generated an +app/assets/javascripts/projects.js.coffee+ and a +app/assets/stylesheets/projects.css.scss+ file.
+
+When these files are requested, they will be processed by the processors provided by the +coffee-script+ and +sass-rails+ gems and then sent back to the browser as JavaScript and CSS respectively.
+
+Additional layers of pre-processing can be requested by adding other extensions. These should be used in the order the processing should be applied. For example, a stylesheet called +app/assets/stylesheets/projects.css.scss.erb+ would first be processed as ERB, then SCSS and finally served as CSS. The same applies to a JavaScript file - +app/assets/javascripts/projects.js.coffee.erb+ would be process as ERB, CoffeeScript and served as JavaScript.
+
+Keep in mind that the order of these pre-processors is important. For example, if we called our JavaScript file +app/assets/javascripts/projects.js.erb.coffee+ then it would be processed with the CoffeeScript interpreter first, which wouldn't understand ERB and therefore we would run into problems.
+
+h3. In Development
+
+TODO: Talk about: Rack::Cache's caching (used in dev and production. The only difference is hashing and headers).
+
+In the development environment assets are compiled and cached on the first request after the server is started. Sprockets sets a +must-validate+ cache-control http header to reduce request overhead on subsequent requests - on these the browser gets a 304 (not-modified) response.
+
+If any of the files in the manifest have changed between requests, the server will respond with a new compiled file.
+
+h4. Debugging Assets
+
+You can put +?debug_assets=true+ or +?debug_assets=1+ at the end of a URL and Sprockets will expand the lines which load the assets. For example, if we had an +app/assets/javascripts/application.js+ file containing these lines:
+
+<plain>
+//= require "projects"
+//= require "tickets"
+</plain>
+
+By default, this would only render this line when used with +<%= javascript_include_tag "application" %>+ in a view or layout:
+
+<html>
+ <script src='/assets/application.js'></script>
+</html>
+
+When the +debug_assets+ parameter is set, this line will be expanded out into three separate lines, separating out the combined file into their parts.
+
+<html>
+ <script src='/assets/application.js'></script>
+ <script src='/assets/projects.js'></script>
+ <script src='/assets/tickets.js'></script>
+</html>
+
+This allows the individual parts of an asset to be rendered and debugged separately.
+
+h3. In Production
+
+In the production environment, assets are served slightly differently.
+
+On the first request the assets are compiled and cached as described above, however the manifest names are altered to include an MD5 hash. Files names typically will look like these:
+
+<plain>
+/assets/application-908e25f4bf641868d8683022a5b62f54.js
+/assets/application-4dd5b109ee3439da54f5bdfd78a80473.css
+</plain>
+
+The MD5 is generated from the contents of the compiled files, and is included in the http +Content-MD5+ header.
+
+Sprockets also sets the +Cache-Control+ http header to +max-age=31536000+. This signals all caches between your server and the client browser that this content (the file served) can be cached for 1 year. The effect of this is to reduce the number of requests for this asset from your server; the asset has a good chance of being in the local browser cache or some intermediate cache.
+
+This behavior is controlled by the setting of +config.action_controller.perform_caching+ setting in Rails (which is +true+ for production, +false+ for everything else). This value is propagated to Sprockets during initialization for use when action_controller is not available.
+
+TODO:
+describe each and the differences between:
+ * Sass-rails's handy +image_url+ helpers
+ * ERB pre-processing and +asset_path+
+
+h4. Precompiling assets
+
+Even though assets are served by Rack::Cache with far-future headers, in high traffic sites this may not be fast enough.
+
+Rails comes bundled with a rake task to compile the manifests to files on disc. These are located in the +public/assets+ directory where they will be served by your web server instead of the Rails application.
+
+TODO: Add section about image assets
+
+The rake task is:
+
+<erb>
+rake assets:precompile
+</erb>
+
+TODO: explain where to use this with Capistrano
+
+TODO: talk about the +config.assets.precompile+ option and the default matcher for files:
+
+<erb>
+[ /\w+\.(?!js|css).+/, "application.js", "application.css" ]
+</erb>
+
+
+Sprockets also creates a "gzip":http://en.wikipedia.org/wiki/Gzip (.gz) of your assets. This prevents your server from contently compressing your assets for each request. You must configure your server to use gzip compression and serve the compressed assets that will be stored in the public/assets folder. The following are some configuration blocks that you can use for common servers.
+NGINX & Apache examples?
+
+
+
+h3. Customizing The Pipeline
+
+h4. CSS
+
+There is currently one option for processing CSS - SCSS. This Gem extends the CSS syntax and offers minification.
+
+The following line will enable SCSS in you project.
+
+<erb>
+config.assets.css_compressor = :scss
+</erb>
+
+This option is for compression only and does not relate to the SCSS language extensions that apply when using the +.scss+ file extension on CSS assets.
+
+h4. Javascript
+
+There are three options available to process javascript - uglifier, closure and yui.
+
+The default Gemfile includes "uglifier":https://github.com/lautis/uglifier. This gem wraps "UglifierJS":https://github.com/mishoo/UglifyJS (written for NodeJS) in Ruby. It compress your code by removing white spaces and other magical things like changing your if and else statements to ternary operators when possible.
+
+TODO: Add detail about the other two
+
+The following line will invoke uglifier for Javascript compression.
+
+<erb>
+config.assets.js_compressor = :uglifier
+</erb>
+
+
+
+h4. Using your own compressor
+
+The compressor config settings for CSS and Javascript will also take an Object.
+
+This object must have a +compress+ method that takes a string as the sole argument and it must return a string.
+
+<erb>
+class Transformer
+ def compress(string)
+ do_something_returning_a_string(string)
+ end
+end
+</erb>
+
+To enable this pass a +new+ Object to the config option in +application.rb+:
+
+<erb>
+config.assets.css_compressor = Transformer.new
+</erb>
+
+
+h4. Changing the _assets_ path
+
+The public path that Sprockets uses by default is +/assets+.
+
+This can be changed to something else:
+
+<erb>
+config.assets.prefix = "/some_other_path"
+</erb>
+
+This is a handy option if you have any existing project (pre Rails 3.1) that already uses this path.
+
+
+h3. Adding Assets to Your Gems
+
+Assets can also come from external sources in the form of gems.
+
+A good example of this is the +jquery-rails+ gem which comes with Rails as the standard JavaScript library gem. This gem contains an engine class which inherits from +Rails::Engine+. By doing this, Rails is informed that the directory for this gem may contain assets and the +app/assets+, +lib/assets+ and +vendor/assets+ directories of this engine are added to the search path of Sprockets.
+
+h3. Making Your Library or Gem a Pre-Processor
+
+"You should be able to register [your gems] on Tilt and Sprockets will find them." - Josh
+Tilt: https://github.com/rtomayko/tilt
+
diff --git a/railties/guides/source/association_basics.textile b/railties/guides/source/association_basics.textile
index 458bfefad8..3c2497e83a 100644
--- a/railties/guides/source/association_basics.textile
+++ b/railties/guides/source/association_basics.textile
@@ -1120,11 +1120,9 @@ h6(#has_many-collection-find). <tt><em>collection</em>.find(...)</tt>
The <tt><em>collection</em>.find</tt> method finds objects within the collection. It uses the same syntax and options as +ActiveRecord::Base.find+.
<ruby>
-@open_orders = @customer.orders.all(:conditions => "open = 1")
+@open_orders = @customer.orders.where(:open => 1)
</ruby>
-NOTE: Starting Rails 3, supplying options to +ActiveRecord::Base.find+ method is discouraged. Use <tt><em>collection</em>.where</tt> instead when you need to pass conditions.
-
h6(#has_many-collection-where). <tt><em>collection</em>.where(...)</tt>
The <tt><em>collection</em>.where</tt> method finds objects within the collection based on the conditions supplied but the objects are loaded lazily meaning that the database is queried only when the object(s) are accessed.
diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile
index 91827fd493..252003edd0 100644
--- a/railties/guides/source/caching_with_rails.textile
+++ b/railties/guides/source/caching_with_rails.textile
@@ -112,7 +112,7 @@ As an example, if you wanted to show all the orders placed on your website in re
<ruby>
<% Order.find_recent.each do |o| %>
- <%= o.buyer.name %> bought <% o.product.name %>
+ <%= o.buyer.name %> bought <%= o.product.name %>
<% end %>
<% cache do %>
@@ -162,17 +162,17 @@ class ProductSweeper < ActionController::Caching::Sweeper
# If our sweeper detects that a Product was created call this
def after_create(product)
- expire_cache_for(product)
+ expire_cache_for(product)
end
# If our sweeper detects that a Product was updated call this
def after_update(product)
- expire_cache_for(product)
+ expire_cache_for(product)
end
# If our sweeper detects that a Product was deleted call this
def after_destroy(product)
- expire_cache_for(product)
+ expire_cache_for(product)
end
private
@@ -345,7 +345,7 @@ ActionController::Base.cache_store = MyCacheStore.new
h4. Cache Keys
-The keys used in a cache can be any object that responds to either +:cache_key+ or to +:to_param+. You can implement the +:cache_key+ method on your classes if you need to generate custom keys. ActiveRecord will generate keys based on the class name and record id.
+The keys used in a cache can be any object that responds to either +:cache_key+ or to +:to_param+. You can implement the +:cache_key+ method on your classes if you need to generate custom keys. Active Record will generate keys based on the class name and record id.
You can use Hashes and Arrays of values as cache keys.
@@ -382,6 +382,7 @@ class ProductsController < ApplicationController
# anything. The default render checks for this using the parameters
# used in the previous call to stale? and will automatically send a
# :not_modified. So that's it, you're done.
+ end
end
</ruby>
diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile
index ad36c6532e..9e3b25d794 100644
--- a/railties/guides/source/command_line.textile
+++ b/railties/guides/source/command_line.textile
@@ -5,7 +5,7 @@ Rails comes with every command line tool you'll need to
* Create a Rails application
* Generate models, controllers, database migrations, and unit tests
* Start a development server
-* Mess with objects through an interactive shell
+* Experiment with objects through an interactive shell
* Profile and benchmark your new creation
endprologue.
@@ -51,21 +51,19 @@ $ rails new commandsapp
Rails will set you up with what seems like a huge amount of stuff for such a tiny command! You've got the entire Rails directory structure now with all the code you need to run our simple application right out of the box.
-INFO: This output will seem very familiar when we get to the +generate+ command. Creepy foreshadowing!
-
h4. +rails server+
-Let's try it! The +rails server+ command launches a small web server named WEBrick which comes bundled with Ruby. You'll use this any time you want to view your work through a web browser.
+The +rails server+ command launches a small web server named WEBrick which comes bundled with Ruby. You'll use this any time you want to access your application through a web browser.
-INFO: WEBrick isn't your only option for serving Rails. We'll get to that in a later section.
+INFO: WEBrick isn't your only option for serving Rails. We'll get to that "later":#different-servers.
-Without any prodding of any kind, +rails server+ will run our new shiny Rails app:
+With no further work, +rails server+ will run our new shiny Rails app:
<shell>
$ cd commandsapp
$ rails server
=> Booting WEBrick
-=> Rails 3.0.0 application starting in development on http://0.0.0.0:3000
+=> Rails 3.1.0 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-04-18 03:20:33] INFO WEBrick 1.3.1
@@ -75,13 +73,21 @@ $ rails server
With just three commands we whipped up a Rails server listening on port 3000. Go to your browser and open "http://localhost:3000":http://localhost:3000, you will see a basic Rails app running.
+You can also use the alias "s" to start the server: <tt>rails s</tt>.
+
+The server can be run on a different port using the +-p+ option. The default development environment can be changed using +-e+.
+
+<shell>
+$ rails server -e production -p 4000
+</shell>
+
h4. +rails generate+
-The +rails generate+ command uses templates to create a whole lot of things. You can always find out what's available by running +rails generate+ by itself. Let's do that:
+The +rails generate+ command uses templates to create a whole lot of things. Running +rails generate+ by itself gives a list of available generators:
<shell>
$ rails generate
-Usage: rails generate generator [args] [options]
+Usage: rails generate GENERATOR [args] [options]
...
...
@@ -97,7 +103,7 @@ Rails:
NOTE: You can install more generators through generator gems, portions of plugins you'll undoubtedly install, and you can even create your own!
-Using generators will save you a large amount of time by writing *boilerplate code*, code that is necessary for the app to work, but not necessary for you to spend time writing. That's what we have computers for.
+Using generators will save you a large amount of time by writing *boilerplate code*, code that is necessary for the app to work.
Let's make our own controller with the controller generator. But what command should we use? Let's ask the generator:
@@ -146,7 +152,8 @@ $ rails generate controller Greetings hello
create test/unit/helpers/greetings_helper_test.rb
invoke assets
create app/assets/javascripts/greetings.js
- create app/assets/stylesheets/greetings.css
+ invoke css
+ create app/assets/stylesheets/greetings.css
</shell>
@@ -169,7 +176,7 @@ Then the view, to display our message (in +app/views/greetings/hello.html.erb+):
<p><%= @message %></p>
</html>
-Deal. Go check it out in your browser. Fire up your server using +rails server+.
+Fire up your server using +rails server+.
<shell>
$ rails server
@@ -182,7 +189,7 @@ The URL will be "http://localhost:3000/greetings/hello":http://localhost:3000/gr
INFO: With a normal, plain-old Rails application, your URLs will generally follow the pattern of http://(host)/(controller)/(action), and a URL like http://(host)/(controller) will hit the *index* action of that controller.
-Rails comes with a generator for data models too:
+Rails comes with a generator for data models too.
<shell>
$ rails generate model
@@ -237,7 +244,7 @@ dependency model
create test/unit/high_score_test.rb
create test/fixtures/high_scores.yml
exists db/migrate
- create db/migrate/20081217071914_create_high_scores.rb
+ create db/migrate/20100209025147_create_high_scores.rb
</shell>
The generator checks that there exist the directories for models, controllers, helpers, layouts, functional and unit tests, stylesheets, creates the views, controller, model and database migration for HighScore (creating the +high_scores+ table and fields), takes care of the route for the *resource*, and new tests for everything.
@@ -267,11 +274,13 @@ h4. +rails console+
The +console+ command lets you interact with your Rails application from the command line. On the underside, +rails console+ uses IRB, so if you've ever used it, you'll be right at home. This is useful for testing out quick ideas with code and changing data server-side without touching the website.
+You can also use the alias "c" to invoke the console: <tt>rails c</tt>.
+
If you wish to test out some code without changing any data, you can do that by invoking +rails console --sandbox+.
<shell>
$ rails console --sandbox
-Loading development environment in sandbox (Rails 3.0.0)
+Loading development environment in sandbox (Rails 3.1.0)
Any modifications you make will be rolled back on exit
irb(main):001:0>
</shell>
@@ -280,13 +289,11 @@ h4. +rails dbconsole+
+rails dbconsole+ figures out which database you're using and drops you into whichever command line interface you would use with it (and figures out the command line parameters to give to it, too!). It supports MySQL, PostgreSQL, SQLite and SQLite3.
-h4. +rails plugin+
+You can also use the alias "db" to invoke the dbconsole: <tt>rails db</tt>.
-The +rails plugin+ command simplifies plugin management; think a miniature version of the Gem utility. Let's walk through installing a plugin. You can call the sub-command +discover+, which sifts through repositories looking for plugins, or call +source+ to add a specific repository of plugins, or you can specify the plugin location directly.
-
-Let's say you're creating a website for a client who wants a small accounting system. Every event having to do with money must be logged, and must never be deleted. Wouldn't it be great if we could override the behavior of a model to never actually take its record out of the database, but instead, just set a field?
+h4. +rails plugin+
-There is such a thing! The plugin we're installing is called +acts_as_paranoid+, and it lets models implement a +deleted_at+ column that gets set when you call destroy. Later, when calling find, the plugin will tack on a database check to filter out "deleted" things.
+The +rails plugin+ command simplifies plugin management. Plugins can be installed by name or their repository URLs. You need to have Git installed if you want to install a plugin from a Git repo. The same holds for Subversion too.
<shell>
$ rails plugin install https://github.com/technoweenie/acts_as_paranoid.git
@@ -304,9 +311,15 @@ h4. +rails runner+
$ rails runner "Model.long_running_method"
</shell>
+You can specify the environment in which the +runner+ command should operate using the +-e+ switch.
+
+<shell>
+$ rails runner -e staging "Model.long_running_method"
+</shell>
+
h4. +rails destroy+
-Think of +destroy+ as the opposite of +generate+. It'll figure out what generate did, and undo it. Believe you-me, the creation of this tutorial used this command many times!
+Think of +destroy+ as the opposite of +generate+. It'll figure out what generate did, and undo it.
<shell>
$ rails generate model Oops
@@ -333,9 +346,29 @@ $ rails destroy model Oops
notempty app
</shell>
-h4. +rake about+
+h3. Rake
+
+Rake is Ruby Make, a standalone Ruby utility that replaces the Unix utility 'make', and uses a 'Rakefile' and +.rake+ files to build up a list of tasks. In Rails, Rake is used for common administration tasks, especially sophisticated ones that build off of each other.
-Check it: Version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application's folder, the current Rails environment name, your app's database adapter, and schema version! +about+ is useful when you need to ask for help, check if a security patch might affect you, or when you need some stats for an existing Rails installation.
+You can get a list of Rake tasks available to you, which will often depend on your current directory, by typing +rake --tasks+. Each task has a description, and should help you find the thing you need.
+
+<shell>
+$ rake --tasks
+(in /home/foobar/commandsapp)
+rake db:abort_if_pending_migrations # Raises an error if there are pending migrations
+rake db:charset # Retrieves the charset for the current environment's database
+rake db:collation # Retrieves the collation for the current environment's database
+rake db:create # Create the database defined in config/database.yml for the current Rails.env
+...
+...
+rake tmp:pids:clear # Clears all files in tmp/pids
+rake tmp:sessions:clear # Clears all files in tmp/sessions
+rake tmp:sockets:clear # Clears all files in tmp/sockets
+</shell>
+
+h4. +about+
+
+<tt>rake about</tt> gives information about version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application's folder, the current Rails environment name, your app's database adapter, and schema version. It is useful when you need to ask for help, check if a security patch might affect you, or when you need some stats for an existing Rails installation.
<shell>
$ rake about
@@ -343,17 +376,98 @@ About your application's environment
Ruby version 1.8.7 (x86_64-linux)
RubyGems version 1.3.6
Rack version 1.1
-Rails version 3.0.0
-Active Record version 3.0.0
-Action Pack version 3.0.0
-Active Resource version 3.0.0
-Action Mailer version 3.0.0
-Active Support version 3.0.0
+Rails version 3.1.0
+Active Record version 3.1.0
+Action Pack version 3.1.0
+Active Resource version 3.1.0
+Action Mailer version 3.1.0
+Active Support version 3.1.0
Middleware ActionDispatch::Static, Rack::Lock, Rack::Runtime, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, Rack::Sendfile, ActionDispatch::Callbacks, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, Rack::MethodOverride, ActionDispatch::Head
Application root /home/foobar/commandsapp
Environment development
</shell>
+h4. +assets+
+
+You can precompile the assets in <tt>app/assets</tt> using <tt>rake assets:precompile</tt> and remove compiled assets using <tt>rake assets:clean</tt>.
+
+h4. +db+
+
+The most common tasks of the +db:+ Rake namespace are +migrate+ and +create+, and it will pay off to try out all of the migration rake tasks (+up+, +down+, +redo+, +reset+). +rake db:version+ is useful when troubleshooting, telling you the current version of the database.
+
+More information about migrations can be found in the "Migrations":migrations.html guide.
+
+h4. +doc+
+
+The +doc:+ namespace has the tools to generate documentation for your app, API documentation, guides. Documentation can also be stripped which is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform.
+
+* +rake doc:app+ generates documentation for your application in +doc/app+.
+* +rake doc:guides+ generates Rails guides in +doc/guides+.
+* +rake doc:rails+ generates API documentation for Rails in +doc/api+.
+* +rake doc:plugins+ generates API documentation for all the plugins installed in the application in +doc/plugins+.
+* +rake doc:clobber_plugins+ removes the generated documentation for all plugins.
+
+h4. +notes+
+
++rake notes+ will search through your code for comments beginning with FIXME, OPTIMIZE or TODO. The search is only done in files with extension +.builder+, +.rb+, +.rxml+, +.rhtml+ and +.erb+ for both default and custom annotations.
+
+<shell>
+$ rake notes
+(in /home/foobar/commandsapp)
+app/controllers/admin/users_controller.rb:
+ * [ 20] [TODO] any other way to do this?
+ * [132] [FIXME] high priority for next deploy
+
+app/model/school.rb:
+ * [ 13] [OPTIMIZE] refactor this code to make it faster
+ * [ 17] [FIXME]
+</shell>
+
+If you are looking for a specific annotation, say FIXME, you can use +rake notes:fixme+. Note that you have to lower case the annotation's name.
+
+<shell>
+$ rake notes:fixme
+(in /home/foobar/commandsapp)
+app/controllers/admin/users_controller.rb:
+ * [132] high priority for next deploy
+
+app/model/school.rb:
+ * [ 17]
+</shell>
+
+You can also use custom annotations in your code and list them using +rake notes:custom+ by specifying the annotation using an environment variable +ANNOTATION+.
+
+<shell>
+$ rake notes:custom ANNOTATION=BUG
+(in /home/foobar/commandsapp)
+app/model/post.rb:
+ * [ 23] Have to fix this one before pushing!
+</shell>
+
+NOTE. When using specific annotations and custom annotations, the annotation name (FIXME, BUG etc) is not displayed in the output lines.
+
+h4. +routes+
+
++rake routes+ will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with.
+
+h4. +test+
+
+INFO: A good description of unit testing in Rails is given in "A Guide to Testing Rails Applications":testing.html
+
+Rails comes with a test suite called Test::Unit. It is through the use of tests that Rails itself is so stable, and the slew of people working on Rails can prove that everything works as it should.
+
+The +test:+ namespace helps in running the different tests you will (hopefully!) write.
+
+h4. +tmp+
+
+The <tt>Rails.root/tmp</tt> directory is, like the *nix /tmp directory, the holding place for temporary files like sessions (if you're using a file store for files), process id files, and cached actions. The +tmp:+ namespace tasks will help you clear them if you need to if they've become overgrown, or create them in case of deletions gone awry.
+
+h4. Miscellaneous
+
+* +rake stats+ is great for looking at statistics on your code, displaying things like KLOCs (thousands of lines of code) and your code to test ratio.
+* +rake secret+ will give you a pseudo-random key to use for your session secret.
+* <tt>rake time:zones:all</tt> lists all the timezones Rails knows about.
+
h3. The Rails Advanced Command Line
More advanced use of the command line is focused around finding useful (even surprising at times) options in the utilities, and fitting those to your needs and specific work flow. Listed here are some tricks up Rails' sleeve.
@@ -393,7 +507,7 @@ We had to create the *gitapp* directory and initialize an empty git repository b
<shell>
$ cat config/database.yml
-# PostgreSQL. Versions 7.4 and 8.x are supported.
+# PostgreSQL. Versions 8.2 and up are supported.
#
# Install the ruby-postgres driver:
# gem install ruby-postgres
@@ -414,11 +528,13 @@ development:
...
</shell>
-It also generated some lines in our database.yml configuration corresponding to our choice of PostgreSQL for database. The only catch with using the SCM options is that you have to make your application's directory first, then initialize your SCM, then you can run the +rails new+ command to generate the basis of your app.
+It also generated some lines in our database.yml configuration corresponding to our choice of PostgreSQL for database.
+
+NOTE. The only catch with using the SCM options is that you have to make your application's directory first, then initialize your SCM, then you can run the +rails new+ command to generate the basis of your app.
-h4. +server+ with Different Backends
+h4(#different-servers). +server+ with Different Backends
-Many people have created a large number different web servers in Ruby, and many of them can be used to run Rails. Since version 2.3, Rails uses Rack to serve its webpages, which means that any webserver that implements a Rack handler can be used. This includes WEBrick, Mongrel, Thin, and Phusion Passenger (to name a few!).
+Many people have created a large number of different web servers in Ruby, and many of them can be used to run Rails. Since version 2.3, Rails uses Rack to serve its webpages, which means that any webserver that implements a Rack handler can be used. This includes WEBrick, Mongrel, Thin, and Phusion Passenger (to name a few!).
NOTE: For more details on the Rack integration, see "Rails on Rack":rails_on_rack.html.
@@ -437,157 +553,6 @@ Successfully installed mongrel-1.1.5
Installing RDoc documentation for mongrel-1.1.5...
$ rails server mongrel
=> Booting Mongrel (use 'rails server webrick' to force WEBrick)
-=> Rails 3.0.0 application starting on http://0.0.0.0:3000
+=> Rails 3.1.0 application starting on http://0.0.0.0:3000
...
</shell>
-
-h4. The Rails Generation: Generators
-
-INFO: For a good rundown on generators, see "Understanding Generators":http://wiki.rubyonrails.org/rails/pages/UnderstandingGenerators. A lot of its material is presented here.
-
-Generators are code that generates code. Let's experiment by building one. Our generator will generate a text file.
-
-The Rails generator by default looks in these places for available generators, where Rails.root is the root of your Rails application, like /home/foobar/commandsapp:
-
-* Rails.root/lib/generators
-* Rails.root/vendor/generators
-* Inside any plugin with a directory like "generators" or "rails_generators"
-* ~/.rails/generators
-* Inside any Gem you have installed with a name ending in "_generator"
-* Inside any Gem installed with a "rails_generators" path, and a file ending in "_generator.rb"
-* Finally, the builtin Rails generators (controller, model, mailer, etc.)
-
-Let's try the fourth option (in our home directory), which will be easy to clean up later:
-
-<shell>
-$ mkdir -p ~/.rails/generators/tutorial_test/templates
-$ touch ~/.rails/generators/tutorial_test/templates/tutorial.erb
-$ touch ~/.rails/generators/tutorial_test/tutorial_test_generator.rb
-</shell>
-
-We'll fill +tutorial_test_generator.rb+ out with:
-
-<ruby>
-class TutorialTestGenerator < Rails::Generator::Base
- def initialize(*runtime_args)
- super(*runtime_args)
- @tut_args = runtime_args
- end
-
- def manifest
- record do |m|
- m.directory "public"
- m.template "tutorial.erb", File.join("public", "tutorial.txt"),
- :assigns => { :args => @tut_args }
- end
- end
-end
-</ruby>
-
-We take whatever args are supplied, save them to an instance variable, and literally copying from the Rails source, implement a +manifest+ method, which calls +record+ with a block, and we:
-
-* Check there's a *public* directory. You bet there is.
-* Run the ERB template called "tutorial.erb".
-* Save it into "Rails.root/public/tutorial.txt".
-* Pass in the arguments we saved through the +:assigns+ parameter.
-
-Next we'll build the template:
-
-<shell>
-$ cat ~/.rails/generators/tutorial_test/templates/tutorial.erb
-I'm a template!
-
-I got assigned some args:
-<%= require 'pp'; PP.pp(args, "") %>
-</shell>
-
-Then we'll make sure it got included in the list of available generators:
-
-<shell>
-$ rails generate
-...
-...
-Installed Generators
- User: tutorial_test
-</shell>
-
-SWEET! Now let's generate some text, yeah!
-
-<shell>
-$ rails generate tutorial_test arg1 arg2 arg3
- exists public
- create public/tutorial.txt
-</shell>
-
-And the result:
-
-<shell>
-$ cat public/tutorial.txt
-I'm a template!
-
-I got assigned some args:
-[["arg1", "arg2", "arg3"],
- {:collision=>:ask,
- :quiet=>false,
- :generator=>"tutorial_test",
- :command=>:create}]
-</shell>
-
-Tada!
-
-h4. Rake is Ruby Make
-
-Rake is a standalone Ruby utility that replaces the Unix utility 'make', and uses a 'Rakefile' and +.rake+ files to build up a list of tasks. In Rails, Rake is used for common administration tasks, especially sophisticated ones that build off of each other.
-
-You can get a list of Rake tasks available to you, which will often depend on your current directory, by typing +rake --tasks+. Each task has a description, and should help you find the thing you need.
-
-<shell>
-$ rake --tasks
-(in /home/foobar/commandsapp)
-rake db:abort_if_pending_migrations # Raises an error if there are pending migrations
-rake db:charset # Retrieves the charset for the current environment's database
-rake db:collation # Retrieves the collation for the current environment's database
-rake db:create # Create the database defined in config/database.yml for the current Rails.env
-...
-...
-rake tmp:pids:clear # Clears all files in tmp/pids
-rake tmp:sessions:clear # Clears all files in tmp/sessions
-rake tmp:sockets:clear # Clears all files in tmp/sockets
-</shell>
-
-h5. +db:+ Database
-
-The most common tasks of the +db:+ Rake namespace are +migrate+ and +create+, and it will pay off to try out all of the migration rake tasks (+up+, +down+, +redo+, +reset+). +rake db:version+ is useful when troubleshooting, telling you the current version of the database.
-
-h5. +doc:+ Documentation
-
-If you want to strip out or rebuild any of the Rails documentation (including this guide!), the +doc:+ namespace has the tools. Stripping documentation is mainly useful for slimming your codebase, like if you're writing a Rails application for an embedded platform.
-
-h5. +notes:+ Code note enumeration
-
-These tasks will search through your code for commented lines beginning with "FIXME", "OPTIMIZE", "TODO", or any custom annotation (like XXX) and show you them.
-
-h5. +test:+ Rails tests
-
-INFO: A good description of unit testing in Rails is given in "A Guide to Testing Rails Applications":testing.html
-
-Rails comes with a test suite called Test::Unit. It is through the use of tests that Rails itself is so stable, and the slew of people working on Rails can prove that everything works as it should.
-
-The +test:+ namespace helps in running the different tests you will (hopefully!) write.
-
-h5. +time:+ Timezones
-
-You can list all the timezones Rails knows about with +rake time:zones:all+, which is useful just in day-to-day life.
-
-h5. +tmp:+ Temporary files
-
-The tmp directory is, like in the *nix /tmp directory, the holding place for temporary files like sessions (if you're using a file store for files), process id files, and cached actions. The +tmp:+ namespace tasks will help you clear them if you need to if they've become overgrown, or create them in case of deletions gone awry.
-
-h5. Miscellaneous Tasks
-
- +rake stats+ is great for looking at statistics on your code, displaying things like KLOCs (thousands of lines of code) and your code to test ratio.
-
- +rake secret+ will give you a pseudo-random key to use for your session secret.
-
- +rake routes+ will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with.
-
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index fbe3d46367..8e6010ff79 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -18,7 +18,7 @@ Rails offers four standard spots to place initialization code:
h3. Running Code Before Rails
-In the rare event that your application needs to run some code before Rails itself is loaded, put it above the call to +require 'rails/all'+ in your +config/application.rb+.
+In the rare event that your application needs to run some code before Rails itself is loaded, put it above the call to +require 'rails/all'+ in +config/application.rb+.
h3. Configuring Rails Components
@@ -52,12 +52,14 @@ end
* +config.asset_host+ sets the host for the assets. Useful when CDNs are used for hosting assets, or when you want to work around the concurrency constraints builtin in browsers using different domain aliases. Shorter version of +config.action_controller.asset_host+.
-* +config.asset_path+ can take a callable, a string, or be +nil+. Default is +nil+. If set, this configuration parameter let's you decorate asset paths. For example, the normal path for +blog.js+ would be +/javascripts/blog.js+, let that absolute path be +path+. If +config.asset_path+ is a callable, Rails calls it when generating asset paths passing +path+ as argument. If +config.asset_path+ is a string, it is expected to be a +sprintf+ format string with a +%s+ where +path+ will get inserted. In either case, Rails outputs the decorated path. *This option is ignored if the asset pipeline is enabled, which is by default*. Shorter version of +config.action_controller.asset_path+.
+* +config.asset_path+ lets you decorate asset paths. This can be a callable, a string, or be +nil+ which is the default. For example, the normal path for +blog.js+ would be +/javascripts/blog.js+, let that absolute path be +path+. If +config.asset_path+ is a callable, Rails calls it when generating asset paths passing +path+ as argument. If +config.asset_path+ is a string, it is expected to be a +sprintf+ format string with a +%s+ where +path+ will get inserted. In either case, Rails outputs the decorated path. Shorter version of +config.action_controller.asset_path+.
<ruby>
config.asset_path = proc { |path| "/blog/public#{path}" }
</ruby>
+NOTE. The +config.asset_path+ configuration is ignored if the asset pipeline is enabled, which is the default.
+
* +config.autoload_once_paths+ accepts an array of paths from which Rails will autoload constants that won't be wiped per request. Relevant if +config.cache_classes+ is false, which is the case in development mode by default. Otherwise, all autoloading happens only once. All elements of this array must also be in +autoload_paths+. Default is an empty array.
* +config.autoload_paths+ accepts an array of paths from which Rails will autoload constants. Default is all directories under +app+.
@@ -84,11 +86,11 @@ config.asset_path = proc { |path| "/blog/public#{path}" }
* +config.log_level+ defines the verbosity of the Rails logger. This option defaults to +:debug+ for all modes except production, where it defaults to +:info+.
-* +config.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ +Logger+ class. Defaults to an instance of +ActiveSupport::BufferedLogger+, with auto flushing off in production mode.
+* +config.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby +Logger+ class. Defaults to an instance of +ActiveSupport::BufferedLogger+, with auto flushing off in production mode.
-* +config.middleware+ allows you to configure the application's middleware. This is covered in depth in the "Configuring Middleware":configuring-middleware section below.
+* +config.middleware+ allows you to configure the application's middleware. This is covered in depth in the "Configuring Middleware":#configuring-middleware section below.
-* +config.plugins+ accepts the list of plugins to load. If this is set to +nil+, default, all plugins will be loaded. If this is set to +[]+, no plugins will be loaded. Otherwise, plugins will be loaded in the order specified. This option let's you enforce some particular loading order, useful when dependencies between plugins require it. For that use case, put first the plugins you want to be loaded in a certain order, and then the special symbol +:all+ to have the rest loaded without the need to specify them.
+* +config.plugins+ accepts the list of plugins to load. The default is +nil+ in which case all plugins will be loaded. If this is set to +[]+, no plugins will be loaded. Otherwise, plugins will be loaded in the order specified. This option lets you enforce some particular loading order, useful when dependencies between plugins require it. For that use case, put first the plugins you want to be loaded in a certain order, and then the special symbol +:all+ to have the rest loaded without the need to specify them.
* +config.preload_frameworks+ enables or disables preloading all frameworks at startup. Enabled by +config.threadsafe!+. Defaults to +nil+, so is disabled.
@@ -96,9 +98,9 @@ config.asset_path = proc { |path| "/blog/public#{path}" }
* +config.secret_token+ used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering. Applications get +config.secret_token+ initialized to a random key in +config/initializers/secret_token.rb+.
-* +config.serve_static_assets+ configures Rails to serve static assets. Defaults to true, but in the production environment is turned off. The server software used to run the application should be used to serve the assets instead.
+* +config.serve_static_assets+ configures Rails itself to serve static assets. Defaults to true, but in the production environment is turned off as the server software (e.g. Nginx or Apache) used to run the application should serve static assets instead. Unlike the default setting set this to true when running (absolutely not recommended!) or testing your app in production mode using WEBrick. Otherwise you won´t be able use page caching and requests for files that exist regularly under the public directory will anyway hit your Rails app.
-* +config.session_store+ is usually set up in +config/initializers/session_store.rb+ and specifies what class to use to store the session. Possible values are +:cookie_store+, default, +:mem_cache_store+, and +:disabled+. The last one tells Rails not to deal with sessions. Custom session stores can also be specified like so:
+* +config.session_store+ is usually set up in +config/initializers/session_store.rb+ and specifies what class to use to store the session. Possible values are +:cookie_store+ which is the default, +:mem_cache_store+, and +:disabled+. The last one tells Rails not to deal with sessions. Custom session stores can also be specified:
<ruby>
config.session_store :my_custom_store
@@ -114,52 +116,71 @@ WARNING: Threadsafe operation is incompatible with the normal workings of develo
* +config.whiny_nils+ enables or disables warnings when a certain set of methods are invoked on +nil+ and it does not respond to them. Defaults to true in development and test environments.
+h4. Configuring Assets
+
+Rails 3.1, by default, is set up to use the +sprockets+ gem to manage assets within an application. This gem concatenates and compresses assets in order to make serving them much less painful.
+
+* +config.assets.css_compressor+ defines the CSS compressor to use. Only supported value at the moment is +:yui+, which uses the +yui-compressor+ gem.
+
* +config.assets.enabled+ a flag that controls whether the asset pipeline is enabled. It is explicitly initialized in +config/application.rb+.
+* +config.assets.js_compressor+ defines the JavaScript compressor to use. Possible values are +:closure+, +:uglifier+ and +:yui+ which require the use of the +closure-compiler+, +uglifier+ or +yui-compressor+ gems respectively.
+
+* +config.assets.paths+ contains the paths which are used to look for assets. Appending paths to this configuration option will cause those paths to be used in the search for assets.
+
+* +config.assets.precompile+ allows you to specify additional assets (other than +application.css+ and +application.js+) which are to be precompiled when +rake assets:precompile+ is run.
+
+* +config.assets.prefix+ defines the prefix where assets are served from. Defaults to +/assets+.
+
+
h4. Configuring Generators
Rails 3 allows you to alter what generators are used with the +config.generators+ method. This method takes a block:
<ruby>
- config.generators do |g|
- g.orm :active_record
- g.test_framework :test_unit
- end
+config.generators do |g|
+ g.orm :active_record
+ g.test_framework :test_unit
+end
</ruby>
The full set of methods that can be used in this block are as follows:
-* +force_plural+ allows pluralized model names. Defaults to _false_.
-* +helper+ defines whether or not to generate helpers. Defaults to _true_.
-* +orm+ defines which orm to use. Defaults to _nil_, so will use Active Record by default.
-* +integration_tool+ defines which integration tool to use. Defaults to _nil_.
-* +performance_tool+ defines which performance tool to use. Defaults to _nil_.
+* +assets+ allows to create assets on generating a scaffold. Defaults to +true+.
+* +force_plural+ allows pluralized model names. Defaults to +false+.
+* +helper+ defines whether or not to generate helpers. Defaults to +true+.
+* +integration_tool+ defines which integration tool to use. Defaults to +nil+.
+* +javascripts+ turns on the hook for javascripts in generators. Used in Rails for when the +scaffold+ generator is ran. Defaults to +true+.
+* +javascript_engine+ configures the engine to be used (for eg. coffee) when generating assets. Defaults to +nil+.
+* +orm+ defines which orm to use. Defaults to +false+ and will use Active Record by default.
+* +performance_tool+ defines which performance tool to use. Defaults to +nil+.
* +resource_controller+ defines which generator to use for generating a controller when using +rails generate resource+. Defaults to +:controller+.
* +scaffold_controller+ different from +resource_controller+, defines which generator to use for generating a _scaffolded_ controller when using +rails generate scaffold+. Defaults to +:scaffold_controller+.
-* +stylesheets+ turns on the hook for stylesheets in generators. Used in Rails for when the +scaffold+ generator is ran, but this hook can be used in other generates as well.
-* +test_framework+ defines which test framework to use. Defaults to _nil_, so will use Test::Unit by default.
+* +stylesheets+ turns on the hook for stylesheets in generators. Used in Rails for when the +scaffold+ generator is ran, but this hook can be used in other generates as well. Defaults to +true+.
+* +stylesheet_engine+ configures the stylesheet engine (for eg. sass) to be used when generating assets. Defaults to +:css+.
+* +test_framework+ defines which test framework to use. Defaults to +false+ and will use Test::Unit by default.
* +template_engine+ defines which template engine to use, such as ERB or Haml. Defaults to +:erb+.
h4. Configuring Middleware
Every Rails application comes with a standard set of middleware which it uses in this order in the development environment:
-* +Rack::SSL+ Will force every request to be under HTTPS protocol. Will be available if +config.force_ssl+ is set to _true_.
-* +ActionDispatch::Static+ is used to serve static assets. Disabled if +config.serve_static_assets+ is _true_.
-* +Rack::Lock+ Will wrap the app in mutex so it can only be called by a single thread at a time. Only enabled if +config.action_controller.allow_concurrency+ is set to _false_, which it is by default.
+* +Rack::SSL+ Will force every request to be under HTTPS protocol. Will be available if +config.force_ssl+ is set to +true+.
+* +ActionDispatch::Static+ is used to serve static assets. Disabled if +config.serve_static_assets+ is +true+.
+* +Rack::Lock+ Will wrap the app in mutex so it can only be called by a single thread at a time. Only enabled if +config.action_controller.allow_concurrency+ is set to +false+, which it is by default.
* +ActiveSupport::Cache::Strategy::LocalCache+ Serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread.
* +Rack::Runtime+ Sets an +X-Runtime+ header, containing the time (in seconds) taken to execute the request.
-* +Rails::Rack::Logger+ Will notify the logs that the request has began. After request is complete, flushes all the logs.
-* +ActionDispatch::ShowExceptions+ rescues any exception returned by the application and renders nice exception pages if the request is local or if +config.consider_all_requests_local+ is set to _true_. If +config.action_dispatch.show_exceptions+ is set to _false_, exceptions will be raised regardless.
-* +ActionDispatch::RemoteIp+ checks for IP spoofing attacks. Configurable with the +config.action_dispatch.ip_spoofing_check+ and +config.action_dispatch.trusted_proxies+ settings.
-* +Rack::Sendfile+ The Sendfile middleware intercepts responses whose body is being served from a file and replaces it with a server specific X-Sendfile header. Configurable with +config.action_dispatch.x_sendfile_header+
+* +Rails::Rack::Logger+ Notifies the logs that the request has began. After request is complete, flushes all the logs.
+* +ActionDispatch::ShowExceptions+ Rescues any exception returned by the application and renders nice exception pages if the request is local or if +config.consider_all_requests_local+ is set to +true+. If +config.action_dispatch.show_exceptions+ is set to +false+, exceptions will be raised regardless.
+* +ActionDispatch::RemoteIp+ Checks for IP spoofing attacks. Configurable with the +config.action_dispatch.ip_spoofing_check+ and +config.action_dispatch.trusted_proxies+ settings.
+* +Rack::Sendfile+ Intercepts responses whose body is being served from a file and replaces it with a server specific X-Sendfile header. Configurable with +config.action_dispatch.x_sendfile_header+.
* +ActionDispatch::Callbacks+ Runs the prepare callbacks before serving the request.
-* +ActiveRecord::ConnectionAdapters::ConnectionManagement+ cleans active connections after each request, unless the +rack.test+ key in the request environment is set to _true_.
-* +ActiveRecord::QueryCache+ caches all +SELECT+ queries generated in a request. If an +INSERT+ or +UPDATE+ takes place then the cache is cleaned.
+* +ActiveRecord::ConnectionAdapters::ConnectionManagement+ cleans active connections after each request, unless the +rack.test+ key in the request environment is set to +true+.
+* +ActiveRecord::QueryCache+ caches all SELECT queries generated in a request. If any INSERT or UPDATE takes place then the cache is cleaned.
* +ActionDispatch::Cookies+ sets cookies for the request.
* +ActionDispatch::Session::CookieStore+ is responsible for storing the session in cookies. An alternate middleware can be used for this by changing the +config.action_controller.session_store+ to an alternate value. Additionally, options passed to this can be configured by using +config.action_controller.session_options+.
* +ActionDispatch::Flash+ sets up the +flash+ keys. Only available if +config.action_controller.session_store+ is set to a value.
-* +ActionDispatch::ParamsParser+ parses out parameters from the request into +params+
+* +ActionDispatch::ParamsParser+ parses out parameters from the request into +params+.
* +Rack::MethodOverride+ allows the method to be overridden if +params[:_method]+ is set. This is the middleware which supports the PUT and DELETE HTTP method types.
* +ActionDispatch::Head+ converts HEAD requests to GET requests and serves them as so.
* +ActionDispatch::BestStandardsSupport+ enables "best standards support" so that IE8 renders some elements correctly.
@@ -167,44 +188,44 @@ Every Rails application comes with a standard set of middleware which it uses in
Besides these usual middleware, you can add your own by using the +config.middleware.use+ method:
<ruby>
- config.middleware.use Magical::Unicorns
+config.middleware.use Magical::Unicorns
</ruby>
-This will put the +Magical::Unicorns+ middleware on the end of the stack. If you wish to put this middleware before another use +insert_before+:
+This will put the +Magical::Unicorns+ middleware on the end of the stack. You can use +insert_before+ if you wish to add a middleware before another.
<ruby>
- config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns
+config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns
</ruby>
-There's also +insert_after+ which will insert a middleware _after_ another:
+There's also +insert_after+ which will insert a middleware after another:
<ruby>
- config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns
+config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns
</ruby>
Middlewares can also be completely swapped out and replaced with others:
<ruby>
- config.middleware.swap ActionDispatch::BestStandardsSupport, Magical::Unicorns
+config.middleware.swap ActionDispatch::BestStandardsSupport, Magical::Unicorns
</ruby>
They can also be removed from the stack completely:
<ruby>
- config.middleware.delete ActionDispatch::BestStandardsSupport
+config.middleware.delete ActionDispatch::BestStandardsSupport
</ruby>
h4. Configuring i18n
* +config.i18n.default_locale+ sets the default locale of an application used for i18n. Defaults to +:en+.
-* +config.i18n.load_path+ sets the path Rails uses to look for locale files. Defaults to +config/locales/*.{yml,rb}+
+* +config.i18n.load_path+ sets the path Rails uses to look for locale files. Defaults to +config/locales/*.{yml,rb}+.
h4. Configuring Active Record
<tt>config.active_record</tt> includes a variety of configuration options:
-* +config.active_record.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8.x Logger class, which is then passed on to any new database connections made. You can retrieve this logger by calling +logger+ on either an Active Record model class or an Active Record model instance. Set to nil to disable logging.
+* +config.active_record.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then passed on to any new database connections made. You can retrieve this logger by calling +logger+ on either an Active Record model class or an Active Record model instance. Set to +nil+ to disable logging.
* +config.active_record.primary_key_prefix_type+ lets you adjust the naming for primary key columns. By default, Rails assumes that primary key columns are named +id+ (and this configuration option doesn't need to be set.) There are two other choices:
** +:table_name+ would make the primary key for the Customer class +customerid+
@@ -214,21 +235,21 @@ h4. Configuring Active Record
* +config.active_record.table_name_suffix+ lets you set a global string to be appended to table names. If you set this to +_northwest+, then the Customer class will look for +customers_northwest+ as its table. The default is an empty string.
-* +config.active_record.pluralize_table_names+ specifies whether Rails will look for singular or plural table names in the database. If set to +true+ (the default), then the Customer class will use the +customers+ table. If set to +false+, then the Customers class will use the +customer+ table.
+* +config.active_record.pluralize_table_names+ specifies whether Rails will look for singular or plural table names in the database. If set to true (the default), then the Customer class will use the +customers+ table. If set to false, then the Customer class will use the +customer+ table.
-* +config.active_record.default_timezone+ determines whether to use +Time.local+ (if set to +:local+) or +Time.utc+ (if set to +:utc+) when pulling dates and times from the database. The default is +:utc+ for Rails, although ActiveRecord defaults to +:local+ when used outside of Rails.
+* +config.active_record.default_timezone+ determines whether to use +Time.local+ (if set to +:local+) or +Time.utc+ (if set to +:utc+) when pulling dates and times from the database. The default is +:utc+ for Rails, although Active Record defaults to +:local+ when used outside of Rails.
* +config.active_record.schema_format+ controls the format for dumping the database schema to a file. The options are +:ruby+ (the default) for a database-independent version that depends on migrations, or +:sql+ for a set of (potentially database-dependent) SQL statements.
-* +config.active_record.timestamped_migrations+ controls whether migrations are numbered with serial integers or with timestamps. The default is +true+, to use timestamps, which are preferred if there are multiple developers working on the same application.
+* +config.active_record.timestamped_migrations+ controls whether migrations are numbered with serial integers or with timestamps. The default is true, to use timestamps, which are preferred if there are multiple developers working on the same application.
-* +config.active_record.lock_optimistically+ controls whether ActiveRecord will use optimistic locking. By default this is +true+.
+* +config.active_record.lock_optimistically+ controls whether Active Record will use optimistic locking and is true by default.
* +config.active_record.whitelist_attributes+ will create an empty whitelist of attributes available for mass-assignment security for all models in your app.
The MySQL adapter adds one additional configuration option:
-* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether ActiveRecord will consider all +tinyint(1)+ columns in a MySQL database to be booleans. By default this is +true+.
+* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether Active Record will consider all +tinyint(1)+ columns in a MySQL database to be booleans and is true by default.
The schema dumper adds one additional configuration option:
@@ -244,17 +265,17 @@ h4. Configuring Action Controller
* +config.action_controller.page_cache_directory+ should be the document root for the web server and is set using <tt>Base.page_cache_directory = "/document/root"</tt>. For Rails, this directory has already been set to +Rails.public_path+ (which is usually set to <tt>Rails.root + "/public"</tt>). Changing this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your web server to look in the new location for cached files.
-* +config.action_controller.page_cache_extension+ configures the extension used for cached pages saved to +page_cache_directory+. Defaults to +.html+
+* +config.action_controller.page_cache_extension+ configures the extension used for cached pages saved to +page_cache_directory+. Defaults to +.html+.
-* +config.action_controller.perform_caching+ configures whether the application should perform caching or not. Set to _false_ in development mode, _true_ in production.
+* +config.action_controller.perform_caching+ configures whether the application should perform caching or not. Set to false in development mode, true in production.
* +config.action_controller.default_charset+ specifies the default character set for all renders. The default is "utf-8".
-* +config.action_controller.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Controller. Set to nil to disable logging.
+* +config.action_controller.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action Controller. Set to +nil+ to disable logging.
* +config.action_controller.request_forgery_protection_token+ sets the token parameter name for RequestForgery. Calling +protect_from_forgery+ sets it to +:authenticity_token+ by default.
-* +config.action_controller.allow_forgery_protection+ enables or disables CSRF protection. By default this is +false+ in test mode and +true+ in all other modes.
+* +config.action_controller.allow_forgery_protection+ enables or disables CSRF protection. By default this is false in test mode and true in all other modes.
* +config.action_controller.relative_url_root+ can be used to tell Rails that you are deploying to a subdirectory. The default is +ENV['RAILS_RELATIVE_URL_ROOT']+.
@@ -288,45 +309,49 @@ h4. Configuring Action View
There are only a few configuration options for Action View, starting with four on +ActionView::Base+:
-* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| %Q(%&lt;div class=&quot;field_with_errors&quot;&gt;#{html_tag}&lt;/div&gt;).html_safe }</tt>
+* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is
+
+<ruby>
+Proc.new { |html_tag, instance| %Q(<div class="field_with_errors">#{html_tag}</div>).html_safe }
+</ruby>
* +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+.
-* +config.action_view.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Mailer. Set to nil to disable logging.
+* +config.action_view.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action Mailer. Set to +nil+ to disable logging.
* +config.action_view.erb_trim_mode+ gives the trim mode to be used by ERB. It defaults to +'-'+. See the "ERB documentation":http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/ for more information.
* +config.action_view.javascript_expansions+ is a hash containing expansions that can be used for the JavaScript include tag. By default, this is defined as:
<ruby>
- config.action_view.javascript_expansions = { :defaults => ['prototype', 'effects', 'dragdrop', 'controls', 'rails'] }
+config.action_view.javascript_expansions = { :defaults => %w(jquery jquery_ujs) }
</ruby>
However, you may add to this by defining others:
<ruby>
- config.action_view.javascript_expansions[:jquery] = ["jquery", "jquery-ui"]
+config.action_view.javascript_expansions[:prototype] = ['prototype', 'effects', 'dragdrop', 'controls']
</ruby>
And can reference in the view with the following code:
<ruby>
- <%= javascript_include_tag :jquery %>
+<%= javascript_include_tag :prototype %>
</ruby>
* +config.action_view.stylesheet_expansions+ works in much the same way as +javascript_expansions+, but has no default key. Keys defined for this hash can be referenced in the view like such:
<ruby>
- <%= stylesheet_link_tag :special %>
+<%= stylesheet_link_tag :special %>
</ruby>
-* +ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids+ With the cache enabled, the asset tag helper methods will make fewer expensive file system calls (the default implementation checks the file system timestamp). However this prevents you from modifying any asset files while the server is running.
+* +config.action_view.cache_asset_ids+ With the cache enabled, the asset tag helper methods will make fewer expensive file system calls (the default implementation checks the file system timestamp). However this prevents you from modifying any asset files while the server is running.
h4. Configuring Action Mailer
There are a number of settings available on +config.action_mailer+:
-* +config.action_mailer.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Mailer. Set to nil to disable logging.
+* +config.action_mailer.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Action Mailer. Set to +nil+ to disable logging.
* +config.action_mailer.smtp_settings+ allows detailed configuration for the +:smtp+ delivery method. It accepts a hash of options, which can include any of these options:
** +:address+ - Allows you to use a remote mail server. Just change it from its default "localhost" setting.
@@ -340,25 +365,35 @@ There are a number of settings available on +config.action_mailer+:
** +:location+ - The location of the sendmail executable. Defaults to +/usr/sbin/sendmail+.
** +:arguments+ - The command line arguments. Defaults to +-i -t+.
-* +config.action_mailer.raise_delivery_errors+ specifies whether to raise an error if email delivery cannot be completed. It defaults to +true+.
+* +config.action_mailer.raise_delivery_errors+ specifies whether to raise an error if email delivery cannot be completed. It defaults to true.
* +config.action_mailer.delivery_method+ defines the delivery method. The allowed values are +:smtp+ (default), +:sendmail+, and +:test+.
-* +config.action_mailer.perform_deliveries+ specifies whether mail will actually be delivered. By default this is +true+; it can be convenient to set it to +false+ for testing.
+* +config.action_mailer.perform_deliveries+ specifies whether mail will actually be delivered and is true by default. It can be convenient to set it to false for testing.
* +config.action_mailer.default+ configures Action Mailer defaults. These default to:
<ruby>
- :mime_version => "1.0",
- :charset => "UTF-8",
- :content_type => "text/plain",
- :parts_order => [ "text/plain", "text/enriched", "text/html" ]
+:mime_version => "1.0",
+:charset => "UTF-8",
+:content_type => "text/plain",
+:parts_order => [ "text/plain", "text/enriched", "text/html" ]
+</ruby>
+
+* +config.action_mailer.observers+ registers observers which will be notified when mail is delivered.
+<ruby>
+config.action_mailer.observers = ["MailObserver"]
+</ruby>
+
+* +config.action_mailer.interceptors+ registers interceptors which will be called before mail is sent.
+<ruby>
+config.action_mailer.interceptors = ["MailInterceptor"]
</ruby>
h4. Configuring Active Resource
There is a single configuration setting available on +config.active_resource+:
-* +config.active_resource.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Active Resource. Set to nil to disable logging.
+* +config.active_resource.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then used to log information from Active Resource. Set to +nil+ to disable logging.
h4. Configuring Active Support
@@ -398,7 +433,7 @@ Some parts of Rails can also be configured externally by supplying environment v
h3. Using Initializer Files
-After loading the framework and any gems and plugins in your application, Rails turns to loading initializers. An initializer is any file of Ruby code stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks, plugins and gems are loaded, such as options to configure settings for these parts.
+After loading the framework and any gems and plugins in your application, Rails turns to loading initializers. An initializer is any Ruby file stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks, plugins and gems are loaded, such as options to configure settings for these parts.
NOTE: You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the initializers folder on down.
@@ -406,7 +441,7 @@ TIP: If you have any ordering dependency in your initializers, you can control t
h3. Initialization events
-Rails has 5 initialization events which can be hooked into (listed in order that they are ran):
+Rails has 5 initialization events which can be hooked into (listed in the order that they are ran):
* +before_configuration+: This is run as soon as the application constant inherits from +Rails::Application+. The +config+ calls are evaluated before this happens.
@@ -414,7 +449,7 @@ Rails has 5 initialization events which can be hooked into (listed in order that
* +to_prepare+: Run after the initializers are ran for all Railties (including the application itself), but before eager loading and the middleware stack is built.
-* +before_eager_load+: This is run directly before eager loading occurs, which is the default behaviour for the _production_ environment and not for the +development+ enviroment.
+* +before_eager_load+: This is run directly before eager loading occurs, which is the default behaviour for the _production_ environment and not for the +development+ environment.
* +after_initialize+: Run directly after the initialization of the application, but before the application initializers are run.
@@ -437,7 +472,7 @@ Initializers defined using the +initializer+ method will be ran in the order the
WARNING: You may put your initializer before or after any other initializer in the chain, as long as it is logical. Say you have 4 initializers called "one" through "four" (defined in that order) and you define "four" to go _before_ "four" but _after_ "three", that just isn't logical and Rails will not be able to determine your initializer order.
-The block's argument of the +initialize+ is the instance of the application itself, and so we can access the configuration on it by using the +config+ method as this initializer does.
+The block argument of the +initializer+ method is the instance of the application itself, and so we can access the configuration on it by using the +config+ method as done in the example.
Because +Rails::Application+ inherits from +Rails::Railtie+ (indirectly), you can use the +initializer+ method in +config/application.rb+ to define initializers for the application.
@@ -450,21 +485,21 @@ Serves as a placeholder so that +:load_environment_config+ can be defined to run
*+load_active_support+* Requires +active_support/dependencies+ which sets up the basis for Active Support. Optionally requires +active_support/all+ if +config.active_support.bare+ is un-truthful, which is the default.
-*+preload_frameworks+* Will load all autoload dependencies of Rails automatically if +config.preload_frameworks+ is +true+ or "truthful". By default this configuration option is disabled. In Rails, when internal classes are referenced for the first time they are autoloaded. +:preload_frameworks+ loads all of this at once on initialization.
+*+preload_frameworks+* Loads all autoload dependencies of Rails automatically if +config.preload_frameworks+ is +true+ or "truthful". By default this configuration option is disabled. In Rails, when internal classes are referenced for the first time they are autoloaded. +:preload_frameworks+ loads all of this at once on initialization.
-*+initialize_logger+* Initializes the logger (an +ActiveSupport::BufferedLogger+ object) for the application and makes it accessible at +Rails.logger+, providing that there's no initializer inserted before this point that has defined +Rails.logger+.
+*+initialize_logger+* Initializes the logger (an +ActiveSupport::BufferedLogger+ object) for the application and makes it accessible at +Rails.logger+, provided that no initializer inserted before this point has defined +Rails.logger+.
-*+initialize_cache+* If +RAILS_CACHE+ isn't yet set, initializes the cache by referencing the value in +config.cache_store+ and stores the outcome as +RAILS_CACHE+. If this object responds to the +middleware+ method, its middleware is inserted before +Rack::Runtime+ in the middleware stack.
+*+initialize_cache+* If +RAILS_CACHE+ isn't set yet, initializes the cache by referencing the value in +config.cache_store+ and stores the outcome as +RAILS_CACHE+. If this object responds to the +middleware+ method, its middleware is inserted before +Rack::Runtime+ in the middleware stack.
*+set_clear_dependencies_hook+* Provides a hook for +active_record.set_dispatch_hooks+ to use, which will run before this initializer. This initializer -- which runs only if +cache_classes+ is set to +false+ -- uses +ActionDispatch::Callbacks.after+ to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request.
-*+initialize_dependency_mechanism+* If +config.cache_classes+ is set to +true+, configures +ActiveSupport::Dependencies.mechanism+ to +require+ dependencies rather than +load+ them.
+*+initialize_dependency_mechanism+* If +config.cache_classes+ is true, configures +ActiveSupport::Dependencies.mechanism+ to +require+ dependencies rather than +load+ them.
*+bootstrap_hook+* Runs all configured +before_initialize+ blocks.
*+i18n.callbacks+* In the development environment, sets up a +to_prepare+ callback which will call +I18n.reload!+ if any of the locales have changed since the last request. In production mode this callback will only run on the first request.
-*+active_support.initialize_whiny_nils+* Will require +active_support/whiny_nil+ if +config.whiny_nils+ is set to +true+. This file will output errors such as:
+*+active_support.initialize_whiny_nils+* Requires +active_support/whiny_nil+ if +config.whiny_nils+ is true. This file will output errors such as:
<plain>
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
@@ -480,19 +515,19 @@ The error occurred while evaluating nil.each
*+active_support.deprecation_behavior+* Sets up deprecation reporting for environments, defaulting to +:log+ for development, +:notify+ for production and +:stderr+ for test. If a value isn't set for +config.active_support.deprecation+ then this initializer will prompt the user to configure this line in the current environment's +config/environments+ file. Can be set to an array of values.
-*+active_support.initialize_time_zone+* Sets the default time zone for the application based off the +config.time_zone+ setting, which defaults to "UTC".
+*+active_support.initialize_time_zone+* Sets the default time zone for the application based on the +config.time_zone+ setting, which defaults to "UTC".
*+action_dispatch.configure+* Configures the +ActionDispatch::Http::URL.tld_length+ to be set to the value of +config.action_dispatch.tld_length+.
-*+action_view.cache_asset_ids+* Will set +ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids+ to +false+ when Active Support loads, but only if +config.cache_classes+ is too.
+*+action_view.cache_asset_ids+* Sets +ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids+ to +false+ when Active Support loads, but only if +config.cache_classes+ is too.
*+action_view.javascript_expansions+* Registers the expansions set up by +config.action_view.javascript_expansions+ and +config.action_view.stylesheet_expansions+ to be recognised by Action View and therefore usable in the views.
*+action_view.set_configs+* Sets up Action View by using the settings in +config.action_view+ by +send+'ing the method names as setters to +ActionView::Base+ and passing the values through.
-*+action_controller.logger+* Sets +ActionController::Base.logger+ -- if it's not already set -- to +Rails.logger+.
+*+action_controller.logger+* Sets +ActionController::Base.logger+ -- if it's not already set -- to +Rails.logger+.
-*+action_controller.initialize_framework_caches+* Sets +ActionController::Base.cache_store+ -- if it's not already set -- to +RAILS_CACHE+.
+*+action_controller.initialize_framework_caches+* Sets +ActionController::Base.cache_store+ -- if it's not already set -- to +RAILS_CACHE+.
*+action_controller.set_configs+* Sets up Action Controller by using the settings in +config.action_controller+ by +send+'ing the method names as setters to +ActionController::Base+ and passing the values through.
@@ -506,9 +541,9 @@ The error occurred while evaluating nil.each
*+active_record.initialize_database+* Loads the database configuration (by default) from +config/database.yml+ and establishes a connection for the current environment.
-*+active_record.log_runtime+* Includes +ActiveRecord::Railties::ControllerRuntime+ which is responsible for reporting the length of time Active Record calls took for the request back to the logger.
+*+active_record.log_runtime+* Includes +ActiveRecord::Railties::ControllerRuntime+ which is responsible for reporting the time taken by Active Record calls for the request back to the logger.
-*+active_record.set_dispatch_hooks+* If +config.cache_classes+ is set to false, all reloadable connections to the database will be reset.
+*+active_record.set_dispatch_hooks+* Resets all reloadable connections to the database if +config.cache_classes+ is set to +false+.
*+action_mailer.logger+* Sets +ActionMailer::Base.logger+ -- if it's not already set -- to +Rails.logger+.
@@ -536,10 +571,6 @@ The error occurred while evaluating nil.each
*+load_config_initializers+* Loads all Ruby files from +config/initializers+ in the application, railties and engines. The files in this directory can be used to hold configuration settings that should be made after all of the frameworks and plugins are loaded.
-NOTE: You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the +initializers+ folder on down.
-
-TIP: If you have any ordering dependency in your initializers, you can control the load order by naming. For example, +01_critical.rb+ will be loaded before +02_normal.rb+.
-
*+engines_blank_point+* Provides a point-in-initialization to hook into if you wish to do anything before engines are loaded. After this point, all railtie and engine initializers are ran.
*+add_generator_templates+* Finds templates for generators at +lib/templates+ for the application, railities and engines and adds these to the +config.generators.templates+ setting, which will make the templates available for all generators to reference.
@@ -552,13 +583,13 @@ TIP: If you have any ordering dependency in your initializers, you can control t
*+build_middleware_stack+* Builds the middleware stack for the application, returning an object which has a +call+ method which takes a Rack environment object for the request.
-*+eager_load!+* If +config.cache_classes+ is +true+, runs the +config.before_eager_load+ hooks and then calls +eager_load!+ which will load all the Ruby files from +config.eager_load_paths+.
+*+eager_load!+* If +config.cache_classes+ is true, runs the +config.before_eager_load+ hooks and then calls +eager_load!+ which will load all the Ruby files from +config.eager_load_paths+.
*+finisher_hook+* Provides a hook for after the initialization of process of the application is complete, as well as running all the +config.after_initialize+ blocks for the application, railties and engines.
*+set_routes_reloader+* Configures Action Dispatch to reload the routes file using +ActionDispatch::Callbacks.to_prepare+.
-*+disable_dependency_loading+* Disables the automatic dependency loading if the +config.cache_classes+ is set to +true+ and +config.dependency_loading+ is set to +false+.
+*+disable_dependency_loading+* Disables the automatic dependency loading if the +config.cache_classes+ is set to true and +config.dependency_loading+ is set to false.
h3. Changelog
diff --git a/railties/guides/source/contribute.textile b/railties/guides/source/contribute.textile
index 4bd527d4c7..f9bb80861c 100644
--- a/railties/guides/source/contribute.textile
+++ b/railties/guides/source/contribute.textile
@@ -14,7 +14,7 @@ h3. How to Contribute?
* Sample format : "Active Record Associations":https://github.com/lifo/docrails/blob/3e56a3832415476fdd1cb963980d0ae390ac1ed3/railties/guides/source/association_basics.textile.
* Sample output : "Active Record Associations":association_basics.html.
* You can build the Guides during testing by running +bundle exec rake generate_guides+ in the +railties+ directory.
-* You're encouraged to validate XHTML for the generated guides before commiting your changes by running +bundle exec rake validate_guides+ in the +railties+ directory.
+* You're encouraged to validate XHTML for the generated guides before committing your changes by running +bundle exec rake validate_guides+ in the +railties+ directory.
* Edge guides "can be consulted online":http://edgeguides.rubyonrails.org/. That website is generated periodically from docrails.
h3. What to Contribute?
@@ -33,7 +33,7 @@ h3. What to Contribute?
h3. How is the process?
* The preferred way to contribute is to commit to docrails directly.
-* A new guide is only edited by its author until finished though. In that case feedback can be given in its LH ticket.
+* A new guide is only edited by its author until finished though.
* If you are writing a new guide freely commit to docrails partial work and ping lifo or fxn when done with a first draft.
* Guides reviewers will then provide feedback, some of it possibly in form of direct commits to agilize the process.
* Eventually the guide will be approved and added to the index.
@@ -53,7 +53,7 @@ h3. Rules
* If the same guide writer wants to write multiple guides, that's ideally the situation we'd love to be in! However, that guide writer will only receive the cash prize for all the subsequent guides (and not the GitHub or RPM prizes).
* Our review team will have the final say on whether the guide is complete and of good enough quality.
-All authors should read and follow the "Rails Guides Conventions":https://wiki.github.com/lifo/docrails/rails-guides-conventions and the "Rails API Documentation Conventions":https://wiki.github.com/lifo/docrails/rails-api-documentation-conventions.
+All authors should read and follow the "Rails Guides Conventions":ruby_on_rails_guides_guidelines.html and the "Rails API Documentation Conventions":api_documentation_guidelines.html.
h3. Translations
diff --git a/railties/guides/source/contributing_to_ruby_on_rails.textile b/railties/guides/source/contributing_to_ruby_on_rails.textile
index 5eb925d7d2..e6ec061c9a 100644
--- a/railties/guides/source/contributing_to_ruby_on_rails.textile
+++ b/railties/guides/source/contributing_to_ruby_on_rails.textile
@@ -24,7 +24,7 @@ If you've found a problem in Ruby on Rails which is not a security risk do a sea
At the minimum, your issue report needs a title and descriptive text. But that's only a minimum. You should include as much relevant information as possible. You need to at least post the code sample that has the issue. Even better is to include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself - and others - to replicate the bug and figure out a fix.
-Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating a issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with a "I'm having this problem too" comment.
+Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating an issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with a "I'm having this problem too" comment.
h4. Special Treatment for Security Issues
@@ -90,7 +90,7 @@ This command will install all dependencies except the MySQL and PostgreSQL Ruby
$ rake test
</shell>
-You can also run tests for an specific framework, like Action Pack, by going into its directory and executing the same command:
+You can also run tests for a specific framework, like Action Pack, by going into its directory and executing the same command:
<shell>
$ cd actionpack
@@ -264,7 +264,7 @@ When working with documentation, please take into account the "API Documentation
NOTE: As explained above, ordinary code patches should have proper documentation coverage. docrails is only used for isolated documentation improvements.
-WARNING: docrails has a very strict policy: no code can be touched whatsoever, no matter how trivial or small the change. Only RDoc and guides can be edited via docrails.
+WARNING: docrails has a very strict policy: no code can be touched whatsoever, no matter how trivial or small the change. Only RDoc and guides can be edited via docrails. Also, CHANGELOGs should never be edited in docrails.
If you have an idea for a new guide you can refer to the "contribution page":contribute.html for instructions on getting involved.
@@ -309,7 +309,7 @@ Rails follows a simple set of coding style conventions.
* a = b and not a=b.
* Follow the conventions you see used in the source already.
-These are some guidelines and please use your best judgement in using them.
+These are some guidelines and please use your best judgment in using them.
h4. Sanity Check
@@ -350,7 +350,7 @@ Navigate to the Rails "GitHub repository":https://github.com/rails/rails and pre
Add the new remote to your local repository on your local machine:
<shell>
-$ git remote add mine https://<your user name>@github.com/<your user name>/rails.git
+$ git remote add mine git@github.com:<your user name>/rails.git
</shell>
Push to your remote:
@@ -361,7 +361,7 @@ $ git push mine my_new_branch
h4. Issue a Pull Request
-Navigate to the Rails repository you just pushed to (e.g. https://github.com/<your user name>/rails) and press "Pull Request" in the upper right hand corner.
+Navigate to the Rails repository you just pushed to (e.g. https://github.com/your-user-name/rails) and press "Pull Request" in the upper right hand corner.
Write your branch name in branch field (is filled with master by default) and press "Update Commit Range"
diff --git a/railties/guides/source/credits.html.erb b/railties/guides/source/credits.html.erb
index 65e396be95..da6bd6acdf 100644
--- a/railties/guides/source/credits.html.erb
+++ b/railties/guides/source/credits.html.erb
@@ -9,18 +9,14 @@ Ruby on Rails Guides: Credits
<% end %>
-<h3 class="section">Rails Documentation Team</h3>
+<h3 class="section">Rails Guides Reviewers</h3>
-<%= author('Mike Gunderloy', 'mgunderloy') do %>
- Mike Gunderloy is a consultant with <a href="http://www.actionrails.com">ActionRails</a>. He brings 25 years of experience in a variety of languages to bear on his current work with Rails. His near-daily links and other blogging can be found at <a href="http://afreshcup.com">A Fresh Cup</a> and he <a href="http://twitter.com/MikeG1">twitters</a> too much.
-<% end %>
-
-<%= author('Pratik Naik', 'lifo') do %>
- Pratik Naik is a Ruby on Rails consultant with <a href="http://www.actionrails.com">ActionRails</a> and also a member of the <a href="http://rubyonrails.org/core">Rails core team</a>. He maintains a blog at <a href="http://m.onkey.org">has_many :bugs, :through =&gt; :rails</a> and has an active <a href="http://twitter.com/lifo">twitter account</a>.
+<%= author('Vijay Dev', 'vijaydev', 'vijaydev.jpg') do %>
+ Vijayakumar, found as Vijay Dev on the web, is a web applications developer and an open source enthusiast who lives in Chennai, India. He started using Rails in 2009 and began actively contributing to Rails documentation in late 2010. He <a href="https://twitter.com/vijay_dev">tweets</a> a lot and also <a href="http://vijaydev.wordpress.com">blogs</a>.
<% end %>
<%= author('Xavier Noria', 'fxn', 'fxn.png') do %>
- Xavier Noria has been into Ruby on Rails since 2005. He is a Rails committer and enjoys combining his passion for Rails and his past life as a proofreader of math textbooks. Xavier is currently a Ruby on Rails consultant. Oh, he also <a href="http://twitter.com/fxn">tweets</a> and can be found everywhere as &quot;fxn&quot;.
+ Xavier Noria has been into Ruby on Rails since 2005. He is a Rails core team member and enjoys combining his passion for Rails and his past life as a proofreader of math textbooks. Xavier is currently an independent Ruby on Rails consultant. Oh, he also <a href="http://twitter.com/fxn">tweets</a> and can be found everywhere as &quot;fxn&quot;.
<% end %>
<h3 class="section">Rails Guides Designers</h3>
@@ -31,6 +27,10 @@ Ruby on Rails Guides: Credits
<h3 class="section">Rails Guides Authors</h3>
+<%= author('Ryan Bigg', 'radar', 'radar.png') do %>
+Ryan Bigg works as a consultant at <a href="http://rubyx.com">RubyX</a> and has been working with Rails since 2006. He's co-authoring a book called <a href="http://manning.com/katz">Rails 3 in Action</a> and he's written many gems which can be seen on <a href="http://github.com/radar">his GitHub page</a> and he also tweets prolifically as <a href="http://twitter.com/ryanbigg">@ryanbigg</a>.
+<% end %>
+
<%= author('Frederick Cheung', 'fcheung') do %>
Frederick Cheung is Chief Wizard at Texperts where he has been using Rails since 2006. He is based in Cambridge (UK) and when not consuming fine ales he blogs at <a href="http://www.spacevatican.org">spacevatican.org</a>.
<% end %>
@@ -43,6 +43,10 @@ Ruby on Rails Guides: Credits
Jeff Dean is a software engineer with <a href="http://pivotallabs.com">Pivotal Labs</a>.
<% end %>
+<%= author('Mike Gunderloy', 'mgunderloy') do %>
+ Mike Gunderloy is a consultant with <a href="http://www.actionrails.com">ActionRails</a>. He brings 25 years of experience in a variety of languages to bear on his current work with Rails. His near-daily links and other blogging can be found at <a href="http://afreshcup.com">A Fresh Cup</a> and he <a href="http://twitter.com/MikeG1">twitters</a> too much.
+<% end %>
+
<%= author('Mikel Lindsaar', 'raasdnil') do %>
Mikel Lindsaar has been working with Rails since 2006 and is the author of the Ruby <a href="https://github.com/mikel/mail">Mail gem</a> and core contributor (he helped re-write Action Mailer's API). Mikel is the founder of <a href="http://rubyx.com/">RubyX</a>, has a <a href="http://lindsaar.net/">blog</a> and <a href="http://twitter.com/raasdnil">tweets</a>.
<% end %>
@@ -55,6 +59,10 @@ Ruby on Rails Guides: Credits
James Miller is a software developer for <a href="http://www.jk-tech.com">JK Tech</a> in San Diego, CA. You can find James on GitHub, Gmail, Twitter, and Freenode as &quot;bensie&quot;.
<% end %>
+<%= author('Pratik Naik', 'lifo') do %>
+ Pratik Naik is a Ruby on Rails consultant with <a href="http://www.actionrails.com">ActionRails</a> and also a member of the <a href="http://rubyonrails.org/core">Rails core team</a>. He maintains a blog at <a href="http://m.onkey.org">has_many :bugs, :through =&gt; :rails</a> and has an active <a href="http://twitter.com/lifo">twitter account</a>.
+<% end %>
+
<%= author('Emilio Tagua', 'miloops') do %>
Emilio Tagua &mdash;a.k.a. miloops&mdash; is an Argentinian entrepreneur, developer, open source contributor and Rails evangelist. Cofounder of <a href="http://eventioz.com">Eventioz</a>. He has been using Rails since 2006 and contributing since early 2008. Can be found at gmail, twitter, freenode, everywhere as &quot;miloops&quot;.
<% end %>
diff --git a/railties/guides/source/debugging_rails_applications.textile b/railties/guides/source/debugging_rails_applications.textile
index 6f028805d6..f5bee52b5a 100644
--- a/railties/guides/source/debugging_rails_applications.textile
+++ b/railties/guides/source/debugging_rails_applications.textile
@@ -127,7 +127,7 @@ When something is logged it's printed into the corresponding log if the log leve
The available log levels are: +:debug+, +:info+, +:warn+, +:error+, and +:fatal+, corresponding to the log level numbers from 0 up to 4 respectively. To change the default log level, use
<ruby>
-config.log_level = Logger::WARN # In any environment initializer, or
+config.log_level = :warn # In any environment initializer, or
Rails.logger.level = 0 # at any time
</ruby>
@@ -480,11 +480,7 @@ class Author < ActiveRecord::Base
def find_recent_comments(limit = 10)
debugger
- @recent_comments ||= comments.find(
- :all,
- :conditions => ["created_at > ?", 1.week.ago],
- :limit => limit
- )
+ @recent_comments ||= comments.where("created_at > ?", 1.week.ago).limit(limit)
end
end
</ruby>
@@ -493,7 +489,7 @@ TIP: You can use ruby-debug while using +rails console+. Just remember to +requi
<shell>
$ rails console
-Loading development environment (Rails 2.1.0)
+Loading development environment (Rails 3.1.0)
>> require "ruby-debug"
=> []
>> author = Author.first
@@ -507,15 +503,15 @@ With the code stopped, take a look around:
<shell>
(rdb:1) list
-[6, 15] in /PathTo/project/app/models/author.rb
+[2, 9] in /PathTo/project/app/models/author.rb
+ 2 has_one :editorial
+ 3 has_many :comments
+ 4
+ 5 def find_recent_comments(limit = 10)
6 debugger
- 7 @recent_comments ||= comments.find(
- 8 :all,
- 9 :conditions => ["created_at > ?", 1.week.ago],
- 10 :limit => limit
-=> 11 )
- 12 end
- 13 end
+=> 7 @recent_comments ||= comments.where("created_at > ?", 1.week.ago).limit(limit)
+ 8 end
+ 9 end
</shell>
You are at the end of the line, but... was this line executed? You can inspect the instance variables.
diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile
index a63245acec..9051ede9dd 100644
--- a/railties/guides/source/form_helpers.textile
+++ b/railties/guides/source/form_helpers.textile
@@ -545,7 +545,7 @@ NOTE: In many cases the built-in date pickers are clumsy as they do not aid the
h4. Individual Components
-Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component +select_year+, +select_month+, +select_day+, +select_hour+, +select_minute+, +select_second+. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for +select_year+, "month" for +select_month+ etc.) although this can be overriden with the +:field_name+ option. The +:prefix+ option works in the same way that it does for +select_date+ and +select_time+ and has the same default value.
+Occasionally you need to display just a single date component such as a year or a month. Rails provides a series of helpers for this, one for each component +select_year+, +select_month+, +select_day+, +select_hour+, +select_minute+, +select_second+. These helpers are fairly straightforward. By default they will generate an input field named after the time component (for example "year" for +select_year+, "month" for +select_month+ etc.) although this can be overridden with the +:field_name+ option. The +:prefix+ option works in the same way that it does for +select_date+ and +select_time+ and has the same default value.
The first parameter specifies which value should be selected and can either be an instance of a Date, Time or DateTime, in which case the relevant component will be extracted, or a numerical value. For example
@@ -589,7 +589,7 @@ def upload
end
</ruby>
-Once a file has been uploaded, there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several plugins designed to assist with these. Two of the better known ones are "Attachment-Fu":https://github.com/technoweenie/attachment_fu and "Paperclip":http://www.thoughtbot.com/projects/paperclip.
+Once a file has been uploaded, there are a multitude of potential tasks, ranging from where to store the files (on disk, Amazon S3, etc) and associating them with models to resizing image files and generating thumbnails. The intricacies of this are beyond the scope of this guide, but there are several libraries designed to assist with these. Two of the better known ones are "CarrierWave":https://github.com/jnicklas/carrierwave and "Paperclip":http://www.thoughtbot.com/projects/paperclip.
NOTE: If the user has not selected a file the corresponding parameter will be an empty string.
@@ -712,7 +712,7 @@ You might want to render a form with a set of edit fields for each of a person's
<erb>
<%= form_for @person do |person_form| %>
<%= person_form.text_field :name %>
- <% for address in @person.addresses %>
+ <% @person.addresses.each do |address| %>
<%= person_form.fields_for address, :index => address do |address_form|%>
<%= address_form.text_field :city %>
<% end %>
@@ -777,7 +777,7 @@ If you need to post some data to an external resource it is still great to build
Sometimes when you submit data to an external resource, like payment gateway, fields you can use in your form are limited by an external API. So you may want not to generate an +authenticity_token+ hidden field at all. For doing this just pass +false+ to the +:authenticity_token+ option:
<erb>
-<%= form_tag 'http://farfar.away/form', :authenticity_token => 'external_token') do %>
+<%= form_tag 'http://farfar.away/form', :authenticity_token => false) do %>
Form contents
<% end %>
</erb>
diff --git a/railties/guides/source/generators.textile b/railties/guides/source/generators.textile
index a3181b9ac5..2fa1d6e21d 100644
--- a/railties/guides/source/generators.textile
+++ b/railties/guides/source/generators.textile
@@ -46,7 +46,7 @@ class InitializerGenerator < Rails::Generators::Base
end
</ruby>
-NOTE: +create_file+ is a method provided by +Thor::Actions+ and the documentation for it and its brethren can be found at "rdoc.info":http://rdoc.info/github/wycats/thor/master/Thor/Actions.
+NOTE: +create_file+ is a method provided by +Thor::Actions+. Documentation for +create_file+ and other Thor methods can be found in "Thor's documentation":http://rdoc.info/github/wycats/thor/master/Thor/Actions.html
Our new generator is quite simple: it inherits from +Rails::Generators::Base+ and has one method definition. Each public method in the generator is executed when a generator is invoked. Finally, we invoke the +create_file+ method that will create a file at the given destination with the given content. If you are familiar with the Rails Application Templates API, you'll feel right at home with the new generators API.
@@ -131,7 +131,7 @@ And let's execute our generator:
$ rails generate initializer core_extensions
</shell>
-We can see that now a initializer named core_extensions was created at +config/initializers/core_extensions.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
+We can see that now an initializer named core_extensions was created at +config/initializers/core_extensions.rb+ with the contents of our template. That means that +copy_file+ copied a file in our source root to the destination path we gave. The method +file_name+ is automatically created when we inherit from +Rails::Generators::NamedBase+.
The methods that are available for generators are covered in the "final section":#generator-methods of this guide.
@@ -365,7 +365,7 @@ $ rails generate scaffold Comment body:text
Fallbacks allow your generators to have a single responsibility, increasing code reuse and reducing the amount of duplication.
-h3. Application templates
+h3. Application Templates
Now that you've seen how generators can be used _inside_ an application, did you know they can also be used to _generate_ applications too? This kind of generator is referred as a "template".
diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile
index 1c66115d44..6aca5d3420 100644
--- a/railties/guides/source/getting_started.textile
+++ b/railties/guides/source/getting_started.textile
@@ -5,7 +5,7 @@ This guide covers getting up and running with Ruby on Rails. After reading it, y
* Installing Rails, creating a new Rails application, and connecting your application to a database
* The general layout of a Rails application
* The basic principles of MVC (Model, View Controller) and RESTful design
-* How to quickly generate the starting pieces of a Rails application.
+* How to quickly generate the starting pieces of a Rails application
endprologue.
@@ -177,14 +177,14 @@ In any case, Rails will create a folder in your working directory called <tt>blo
|Gemfile|This file allows you to specify what gem dependencies are needed for your Rails application.|
|README|This is a brief instruction manual for your application. Use it to tell others what your application does, how to set it up, and so on.|
|Rakefile|This file contains batch jobs that can be run from the terminal.|
-|app/|Contains the controllers, models, and views for your application. You'll focus on this folder for the remainder of this guide.|
+|app/|Contains the controllers, models, views and assets for your application. You'll focus on this folder for the remainder of this guide.|
|config/|Configure your application's runtime rules, routes, database, and more.|
|config.ru|Rack configuration for Rack based servers used to start the application.|
|db/|Shows your current database schema, as well as the database migrations. You'll learn about migrations shortly.|
|doc/|In-depth documentation for your application.|
|lib/|Extended modules for your application (not covered in this guide).|
|log/|Application log files.|
-|public/|The only folder seen to the world as-is. This is where your images, JavaScript files, stylesheets (CSS), and other static files go.|
+|public/|The only folder seen to the world as-is. Contains the static files and compiled assets.|
|script/|Contains the rails script that starts your app and can contain other scripts you use to deploy or run your application.|
|test/|Unit tests, fixtures, and other test apparatus. These are covered in "Testing Rails Applications":testing.html|
|tmp/|Temporary files|
@@ -205,8 +205,8 @@ h4. Configuring a Database
Just about every Rails application will interact with a database. The database to use is specified in a configuration file, +config/database.yml+.
If you open this file in a new Rails application, you'll see a default database configuration using SQLite3. The file contains sections for three different environments in which Rails can run by default:
-* The +development+ environment is used on your development computer as you interact manually with the application
-* The +test+ environment is used to run automated tests
+* The +development+ environment is used on your development computer as you interact manually with the application.
+* The +test+ environment is used to run automated tests.
* The +production+ environment is used when you deploy your application for the world to use.
h5. Configuring an SQLite3 Database
@@ -244,7 +244,7 @@ If your development computer's MySQL installation includes a root user with an e
h5. Configuring a PostgreSQL Database
-Finally if you choose to use PostgreSQL, your +config/database.yml+ will be customized to use PostgreSQL databases:
+If you choose to use PostgreSQL, your +config/database.yml+ will be customized to use PostgreSQL databases:
<yaml>
development:
@@ -256,6 +256,41 @@ development:
password:
</yaml>
+h5. Configuring an SQLite3 Database for JRuby Platform
+
+If you choose to use SQLite3 and using JRuby, your +config/database.yml+ will look a little different. Here's the development section:
+
+<yaml>
+development:
+ adapter: jdbcsqlite3
+ database: db/development.sqlite3
+</yaml>
+
+h5. Configuring a MySQL Database for JRuby Platform
+
+If you choose to use MySQL and using JRuby, your +config/database.yml+ will look a little different. Here's the development section:
+
+<yaml>
+development:
+ adapter: jdbcmysql
+ database: blog_development
+ username: root
+ password:
+</yaml>
+
+h5. Configuring a PostgreSQL Database for JRuby Platform
+
+Finally if you choose to use PostgreSQL and using JRuby, your +config/database.yml+ will look a little different. Here's the development section:
+
+<yaml>
+development:
+ adapter: jdbcpostgresql
+ encoding: unicode
+ database: blog_development
+ username: blog
+ password:
+</yaml>
+
Change the username and password in the +development+ section as appropriate.
TIP: You don't have to update the database configurations manually. If you had a look at the options of application generator, you have seen that one of them is named <tt>--database</tt>. It lets you choose an adapter for couple of most used relational databases. You can even run the generator repeatedly: <tt>cd .. && rails new blog --database=mysql</tt>. When you confirm the overwriting of the +config/database.yml+ file, your application will be configured for MySQL instead of SQLite.
@@ -290,7 +325,7 @@ This will fire up an instance of the WEBrick web server by default (Rails can al
TIP: To stop the web server, hit Ctrl+C in the terminal window where it's running. In development mode, Rails does not generally require you to stop the server; changes you make in files will be automatically picked up by the server.
-The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. You can also click on the _About your application’s environment_ link to see a summary of your Application's environment.
+The "Welcome Aboard" page is the _smoke test_ for a new Rails application: it makes sure that you have your software configured correctly enough to serve a page. You can also click on the _About your application’s environment_ link to see a summary of your application's environment.
h4. Say "Hello", Rails
@@ -364,11 +399,11 @@ The scaffold generator will build 15 files in your application, along with some
|app/views/posts/new.html.erb |A view to create a new post|
|app/views/posts/_form.html.erb |A partial to control the overall look and feel of the form used in edit and new views|
|app/helpers/posts_helper.rb |Helper functions to be used from the post views|
+|app/assets/stylesheets/scaffold.css.scss |Cascading style sheet to make the scaffolded views look better|
|test/unit/post_test.rb |Unit testing harness for the posts model|
|test/functional/posts_controller_test.rb |Functional testing harness for the posts controller|
|test/unit/helpers/posts_helper_test.rb |Unit testing harness for the posts helper|
|config/routes.rb |Edited to include routing information for posts|
-|app/assets/stylesheets/scaffold.css.scss |Cascading style sheet to make the scaffolded views look better|
h4. Running a Migration
@@ -413,10 +448,10 @@ h4. Adding a Link
To hook the posts up to the home page you've already created, you can add a link to the home page. Open +app/views/home/index.html.erb+ and modify it as follows:
-<code lang="ruby">
+<ruby>
<h1>Hello, Rails!</h1>
<%= link_to "My Blog", posts_path %>
-</code>
+</ruby>
The +link_to+ method is one of Rails' built-in view helpers. It creates a hyperlink based on text to display and where to go - in this case, to the path for posts.
@@ -503,7 +538,7 @@ def index
end
</ruby>
-+Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array of posts that we store in a instance variable called +@posts+.
++Post.all+ calls the +Post+ model to return all of the posts currently in the database. The result of this call is an array of posts that we store in an instance variable called +@posts+.
TIP: For more information on finding records with Active Record, see "Active Record Query Interface":active_record_querying.html.
@@ -544,7 +579,7 @@ This view iterates over the contents of the +@posts+ array to display content an
* +link_to+ builds a hyperlink to a particular destination
* +edit_post_path+ and +new_post_path+ are helpers that Rails provides as part of RESTful routing. You'll see a variety of these helpers for the different actions that the controller includes.
-NOTE. In previous versions of Rails, you had to use +&lt;%=h post.name %&gt;+ so that any HTML would be escaped before being inserted into the page. In Rails 3.0, this is now the default. To get unescaped HTML, you now use +&lt;%= raw post.name %&gt;+.
+NOTE. In previous versions of Rails, you had to use +&lt;%=h post.name %&gt;+ so that any HTML would be escaped before being inserted into the page. In Rails 3.0, this is now the default. To get unescaped HTML, you now use +&lt;%= raw post.name %&gt;+.
TIP: For more details on the rendering process, see "Layouts and Rendering in Rails":layouts_and_rendering.html.
diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile
index 608643b3d3..0c8e4e974d 100644
--- a/railties/guides/source/i18n.textile
+++ b/railties/guides/source/i18n.textile
@@ -809,7 +809,7 @@ That does not mean you're stuck with these limitations, though. The Ruby I18n ge
I18n.backend = Globalize::Backend::Static.new
</ruby>
-You can also use the Chain backend to chain multiple backends together. This is useful when you want to use standard translations with a Simple backend but store custom application translations in a database or other backends. For example, you could use the ActiveRecord backend and fall back to the (default) Simple backend:
+You can also use the Chain backend to chain multiple backends together. This is useful when you want to use standard translations with a Simple backend but store custom application translations in a database or other backends. For example, you could use the Active Record backend and fall back to the (default) Simple backend:
<ruby>
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile
index 638830cd83..340699419b 100644
--- a/railties/guides/source/initialization.textile
+++ b/railties/guides/source/initialization.textile
@@ -20,15 +20,15 @@ h4. +bin/rails+
The actual +rails+ command is kept in _bin/rails_ at the and goes like this:
<ruby>
- #!/usr/bin/env ruby
-
- begin
- require "rails/cli"
- rescue LoadError
- railties_path = File.expand_path('../../railties/lib', __FILE__)
- $:.unshift(railties_path)
- require "rails/cli"
- end
+#!/usr/bin/env ruby
+
+begin
+ require "rails/cli"
+rescue LoadError
+ railties_path = File.expand_path('../../railties/lib', __FILE__)
+ $:.unshift(railties_path)
+ require "rails/cli"
+end
</ruby>
This file will attempt to load +rails/cli+ and if it cannot find it then add the +railties/lib+ path to the load path (+$:+) and will then try to require it again.
@@ -38,22 +38,22 @@ h4. +railites/lib/rails/cli.rb+
This file looks like this:
<ruby>
- require 'rbconfig'
- require 'rails/script_rails_loader'
+require 'rbconfig'
+require 'rails/script_rails_loader'
- # If we are inside a Rails application this method performs an exec and thus
- # the rest of this script is not run.
- Rails::ScriptRailsLoader.exec_script_rails!
+# If we are inside a Rails application this method performs an exec and thus
+# the rest of this script is not run.
+Rails::ScriptRailsLoader.exec_script_rails!
- require 'rails/ruby_version_check'
- Signal.trap("INT") { puts; exit }
+require 'rails/ruby_version_check'
+Signal.trap("INT") { puts; exit }
- if ARGV.first == 'plugin'
- ARGV.shift
- require 'rails/commands/plugin_new'
- else
- require 'rails/commands/application'
- end
+if ARGV.first == 'plugin'
+ ARGV.shift
+ require 'rails/commands/plugin_new'
+else
+ require 'rails/commands/application'
+end
</ruby>
The +rbconfig+ file here is out of Ruby's standard library and provides us with the +RbConfig+ class which contains useful information dependent on how Ruby was compiled. We'll see this in use in +railties/lib/rails/script_rails_loader+.
@@ -76,46 +76,46 @@ The +rails/script_rails_loader+ file uses +RbConfig::Config+ to gather up the +b
Back in +rails/cli+, the next line is this:
<ruby>
- Rails::ScriptRailsLoader.exec_script_rails!
+Rails::ScriptRailsLoader.exec_script_rails!
</ruby>
This method is defined in +rails/script_rails_loader+ like this:
<ruby>
- def self.exec_script_rails!
- cwd = Dir.pwd
- return unless in_rails_application? || in_rails_application_subdirectory?
- exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
- Dir.chdir("..") do
- # Recurse in a chdir block: if the search fails we want to be sure
- # the application is generated in the original working directory.
- exec_script_rails! unless cwd == Dir.pwd
- end
- rescue SystemCallError
- # could not chdir, no problem just return
+def self.exec_script_rails!
+ cwd = Dir.pwd
+ return unless in_rails_application? || in_rails_application_subdirectory?
+ exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
+ Dir.chdir("..") do
+ # Recurse in a chdir block: if the search fails we want to be sure
+ # the application is generated in the original working directory.
+ exec_script_rails! unless cwd == Dir.pwd
end
+rescue SystemCallError
+ # could not chdir, no problem just return
+end
</ruby>
This method will first check if the current working directory (+cwd+) is a Rails application or is a subdirectory of one. The way to determine this is defined in the +in_rails_application?+ method like this:
<ruby>
- def self.in_rails_application?
- File.exists?(SCRIPT_RAILS)
- end
+def self.in_rails_application?
+ File.exists?(SCRIPT_RAILS)
+end
</ruby>
The +SCRIPT_RAILS+ constant defined earlier is used here, with +File.exists?+ checking for its presence in the current directory. If this method returns +false+, then +in_rails_application_subdirectory?+ will be used:
<ruby>
- def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd))
- File.exists?(File.join(path, SCRIPT_RAILS)) || !path.root? && in_rails_application_subdirectory?(path.parent)
- end
+def self.in_rails_application_subdirectory?(path = Pathname.new(Dir.pwd))
+ File.exists?(File.join(path, SCRIPT_RAILS)) || !path.root? && in_rails_application_subdirectory?(path.parent)
+end
</ruby>
This climbs the directory tree until it reaches a path which contains a +script/rails+ file. If a directory is reached which contains this file then this line will run:
<ruby>
- exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
+exec RUBY, SCRIPT_RAILS, *ARGV if in_rails_application?
</ruby>
This is effectively the same as doing +ruby script/rails [arguments]+. Where +[arguments]+ at this point in time is simply "server".
@@ -125,9 +125,9 @@ h4. +script/rails+
This file looks like this:
<ruby>
- APP_PATH = File.expand_path('../../config/application', __FILE__)
- require File.expand_path('../../config/boot', __FILE__)
- require 'rails/commands'
+APP_PATH = File.expand_path('../../config/application', __FILE__)
+require File.expand_path('../../config/boot', __FILE__)
+require 'rails/commands'
</ruby>
The +APP_PATH+ constant here will be used later in +rails/commands+. The +config/boot+ file that +script/rails+ references is the +config/boot.rb+ file in our application which is responsible for loading Bundler and setting it up.
@@ -137,19 +137,19 @@ h4. +config/boot.rb+
+config/boot.rb+ contains this:
<ruby>
- require 'rubygems'
+require 'rubygems'
- # Set up gems listed in the Gemfile.
- gemfile = File.expand_path('../../Gemfile', __FILE__)
- begin
- ENV['BUNDLE_GEMFILE'] = gemfile
- require 'bundler'
- Bundler.setup
- rescue Bundler::GemNotFound => e
- STDERR.puts e.message
- STDERR.puts "Try running `bundle install`."
- exit!
- end if File.exist?(gemfile)
+# Set up gems listed in the Gemfile.
+gemfile = File.expand_path('../../Gemfile', __FILE__)
+begin
+ ENV['BUNDLE_GEMFILE'] = gemfile
+ require 'bundler'
+ Bundler.setup
+rescue Bundler::GemNotFound => e
+ STDERR.puts e.message
+ STDERR.puts "Try running `bundle install`."
+ exit!
+end if File.exist?(gemfile)
</ruby>
In a standard Rails application, there's a +Gemfile+ which declares all dependencies of the application. +config/boot.rb+ sets +ENV["BUNDLE_GEMFILE"]+ to the location of this file, then requires Bundler and calls +Bundler.setup+ which adds the dependencies of the application (including all the Rails parts) to the load path, making them available for the application to load. The gems that a Rails 3.1 application depends on are as follows:
@@ -186,34 +186,34 @@ h4. +rails/commands.rb+
Once +config/boot.rb+ has finished, the next file that is required is +rails/commands+ which will execute a command based on the arguments passed in. In this case, the +ARGV+ array simply contains +server+ which is extracted into the +command+ variable using these lines:
<ruby>
- aliases = {
- "g" => "generate",
- "c" => "console",
- "s" => "server",
- "db" => "dbconsole"
- }
+aliases = {
+ "g" => "generate",
+ "c" => "console",
+ "s" => "server",
+ "db" => "dbconsole"
+}
- command = ARGV.shift
- command = aliases[command] || command
+command = ARGV.shift
+command = aliases[command] || command
</ruby>
If we used <tt>s</tt> rather than +server+, Rails will use the +aliases+ defined in the file and match them to their respective commands. With the +server+ command, Rails will run this code:
<ruby>
- when 'server'
- # Change to the application's path if there is no config.ru file in current dir.
- # This allows us to run script/rails server from other directories, but still get
- # the main config.ru and properly set the tmp directory.
- Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
-
- require 'rails/commands/server'
- Rails::Server.new.tap { |server|
- # We need to require application after the server sets environment,
- # otherwise the --environment option given to the server won't propagate.
- require APP_PATH
- Dir.chdir(Rails.application.root)
- server.start
- }
+when 'server'
+ # Change to the application's path if there is no config.ru file in current dir.
+ # This allows us to run script/rails server from other directories, but still get
+ # the main config.ru and properly set the tmp directory.
+ Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
+
+ require 'rails/commands/server'
+ Rails::Server.new.tap { |server|
+ # We need to require application after the server sets environment,
+ # otherwise the --environment option given to the server won't propagate.
+ require APP_PATH
+ Dir.chdir(Rails.application.root)
+ server.start
+ }
</ruby>
This file will change into the root of the directory (a path two directories back from +APP_PATH+ which points at +config/application.rb+), but only if the +config.ru+ file isn't found. This then requires +rails/commands/server+ which requires +action_dispatch+ and sets up the +Rails::Server+ class.
@@ -239,7 +239,7 @@ The +methods.rb+ file is responsible for defining methods such as +camelize+, +u
In this file there are a lot of lines such as this inside the +ActiveSupport+ module:
<ruby>
- autoload :Inflector
+autoload :Inflector
</ruby>
Due to the overriding of the +autoload+ method, Ruby will know to look for this file at +activesupport/lib/active_support/inflector.rb+ when the +Inflector+ class is first referenced.
@@ -263,10 +263,10 @@ h4. +rails/commands/server.rb+
The +Rails::Server+ class is defined in this file as inheriting from +Rack::Server+. When +Rails::Server.new+ is called, this calls the +initialize+ method in +rails/commands/server.rb+:
<ruby>
- def initialize(*)
- super
- set_environment
- end
+def initialize(*)
+ super
+ set_environment
+end
</ruby>
Firstly, +super+ is called which calls the +initialize+ method on +Rack::Server+.
@@ -278,10 +278,10 @@ h4. Rack: +lib/rack/server.rb+
The +initialize+ method in +Rack::Server+ simply sets a couple of variables:
<ruby>
- def initialize(options = nil)
- @options = options
- @app = options[:app] if options && options[:app]
- end
+def initialize(options = nil)
+ @options = options
+ @app = options[:app] if options && options[:app]
+end
</ruby>
In this case, +options+ will be +nil+ so nothing happens in this method.
@@ -289,64 +289,64 @@ In this case, +options+ will be +nil+ so nothing happens in this method.
After +super+ has finished in +Rack::Server+, we jump back to +rails/commands/server.rb+. At this point, +set_environment+ is called within the context of the +Rails::Server+ object and this method doesn't appear to do much at first glance:
<ruby>
- def set_environment
- ENV["RAILS_ENV"] ||= options[:environment]
- end
+def set_environment
+ ENV["RAILS_ENV"] ||= options[:environment]
+end
</ruby>
In fact, the +options+ method here does quite a lot. This method is defined in +Rack::Server+ like this:
<ruby>
- def options
- @options ||= parse_options(ARGV)
- end
+def options
+ @options ||= parse_options(ARGV)
+end
</ruby>
Then +parse_options+ is defined like this:
<ruby>
- def parse_options(args)
- options = default_options
+def parse_options(args)
+ options = default_options
- # Don't evaluate CGI ISINDEX parameters.
- # http://hoohoo.ncsa.uiuc.edu/cgi/cl.html
- args.clear if ENV.include?("REQUEST_METHOD")
+ # Don't evaluate CGI ISINDEX parameters.
+ # http://hoohoo.ncsa.uiuc.edu/cgi/cl.html
+ args.clear if ENV.include?("REQUEST_METHOD")
- options.merge! opt_parser.parse! args
- options[:config] = ::File.expand_path(options[:config])
- ENV["RACK_ENV"] = options[:environment]
- options
- end
+ options.merge! opt_parser.parse! args
+ options[:config] = ::File.expand_path(options[:config])
+ ENV["RACK_ENV"] = options[:environment]
+ options
+end
</ruby>
With the +default_options+ set to this:
<ruby>
- def default_options
- {
- :environment => ENV['RACK_ENV'] || "development",
- :pid => nil,
- :Port => 9292,
- :Host => "0.0.0.0",
- :AccessLog => [],
- :config => "config.ru"
- }
- end
+def default_options
+ {
+ :environment => ENV['RACK_ENV'] || "development",
+ :pid => nil,
+ :Port => 9292,
+ :Host => "0.0.0.0",
+ :AccessLog => [],
+ :config => "config.ru"
+ }
+end
</ruby>
There is no +REQUEST_METHOD+ key in +ENV+ so we can skip over that line. The next line merges in the options from +opt_parser+ which is defined plainly in +Rack::Server+
<ruby>
- def opt_parser
- Options.new
- end
+def opt_parser
+ Options.new
+end
</ruby>
The class *is* defined in +Rack::Server+, but is overwritten in +Rails::Server+ to take different arguments. Its +parse!+ method begins like this:
<ruby>
- def parse!(args)
- args, options = args.dup, {}
+def parse!(args)
+ args, options = args.dup, {}
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: rails server [mongrel, thin, etc] [options]"
@@ -362,100 +362,101 @@ h4. +Rails::Server#start+
This method is defined like this:
<ruby>
- def start
- puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
- puts "=> Rails #{Rails.version} application starting in #{Rails.env} on http://#{options[:Host]}:#{options[:Port]}"
- puts "=> Call with -d to detach" unless options[:daemonize]
- trap(:INT) { exit }
- puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
-
- #Create required tmp directories if not found
- %w(cache pids sessions sockets).each do |dir_to_make|
- FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make))
- end
-
- super
- ensure
- # The '-h' option calls exit before @options is set.
- # If we call 'options' with it unset, we get double help banners.
- puts 'Exiting' unless @options && options[:daemonize]
+def start
+ puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
+ puts "=> Rails #{Rails.version} application starting in #{Rails.env} on http://#{options[:Host]}:#{options[:Port]}"
+ puts "=> Call with -d to detach" unless options[:daemonize]
+ trap(:INT) { exit }
+ puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
+
+ #Create required tmp directories if not found
+ %w(cache pids sessions sockets).each do |dir_to_make|
+ FileUtils.mkdir_p(Rails.root.join('tmp', dir_to_make))
end
+
+ super
+ensure
+ # The '-h' option calls exit before @options is set.
+ # If we call 'options' with it unset, we get double help banners.
+ puts 'Exiting' unless @options && options[:daemonize]
+end
</ruby>
This is where the first output of the Rails initialization happens. This method creates a trap for +INT+ signals, so if you +CTRL+C+ the server, it will exit the process. As we can see from the code here, it will create the +tmp/cache+, +tmp/pids+, +tmp/sessions+ and +tmp/sockets+ directories if they don't already exist prior to calling +super+. The +super+ method will call +Rack::Server.start+ which begins its definition like this:
<ruby>
- def start
- if options[:warn]
- $-w = true
- end
+def start
+ if options[:warn]
+ $-w = true
+ end
- if includes = options[:include]
- $LOAD_PATH.unshift(*includes)
- end
+ if includes = options[:include]
+ $LOAD_PATH.unshift(*includes)
+ end
- if library = options[:require]
- require library
- end
+ if library = options[:require]
+ require library
+ end
- if options[:debug]
- $DEBUG = true
- require 'pp'
- p options[:server]
- pp wrapped_app
- pp app
- end
+ if options[:debug]
+ $DEBUG = true
+ require 'pp'
+ p options[:server]
+ pp wrapped_app
+ pp app
+ end
+end
</ruby>
In a Rails application, these options are not set at all and therefore aren't used at all. The first line of code that's executed in this method is a call to this method:
<ruby>
- wrapped_app
+wrapped_app
</ruby>
This method calls another method:
<ruby>
- @wrapped_app ||= build_app app
+@wrapped_app ||= build_app app
</ruby>
Then the +app+ method here is defined like so:
<ruby>
- def app
- @app ||= begin
- if !::File.exist? options[:config]
- abort "configuration #{options[:config]} not found"
- end
-
- app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
- self.options.merge! options
- app
+def app
+ @app ||= begin
+ if !::File.exist? options[:config]
+ abort "configuration #{options[:config]} not found"
end
+
+ app, options = Rack::Builder.parse_file(self.options[:config], opt_parser)
+ self.options.merge! options
+ app
end
+end
</ruby>
The +options[:config]+ value defaults to +config.ru+ which contains this:
<ruby>
- # This file is used by Rack-based servers to start the application.
+# This file is used by Rack-based servers to start the application.
- require ::File.expand_path('../config/environment', __FILE__)
- run YourApp::Application
+require ::File.expand_path('../config/environment', __FILE__)
+run YourApp::Application
</ruby>
The +Rack::Builder.parse_file+ method here takes the content from this +config.ru+ file and parses it using this code:
<ruby>
- app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app",
+app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app",
TOPLEVEL_BINDING, config
</ruby>
The <ruby>initialize</ruby> method will take the block here and execute it within an instance of +Rack::Builder+. This is where the majority of the initialization process of Rails happens. The chain of events that this simple line sets off will be the focus of a large majority of this guide. The +require+ line for +config/environment.rb+ in +config.ru+ is the first to run:
<ruby>
- require ::File.expand_path('../config/environment', __FILE__)
+require ::File.expand_path('../config/environment', __FILE__)
</ruby>
h4. +config/environment.rb+
@@ -475,7 +476,7 @@ h3. Loading Rails
The next line in +config/application.rb+ is:
<ruby>
- require 'rails/all'
+require 'rails/all'
</ruby>
h4. +railties/lib/rails/all.rb+
@@ -483,20 +484,20 @@ h4. +railties/lib/rails/all.rb+
This file is responsible for requiring all the individual parts of Rails like so:
<ruby>
- require "rails"
+require "rails"
- %w(
+%w(
active_record
action_controller
action_mailer
active_resource
rails/test_unit
- ).each do |framework|
- begin
- require "#{framework}/railtie"
- rescue LoadError
- end
+).each do |framework|
+ begin
+ require "#{framework}/railtie"
+ rescue LoadError
end
+end
</ruby>
First off the line is the +rails+ require itself.
@@ -518,9 +519,9 @@ h4. +active_support/core_ext/kernel/reporting.rb+
This is the first of the many Active Support core extensions that come with Rails. This one in particular defines methods in the +Kernel+ module which is mixed in to the +Object+ class so the methods are available on +main+ and can therefore be called like this:
<ruby>
- silence_warnings do
- # some code
- end
+silence_warnings do
+ # some code
+end
</ruby>
These methods can be used to silence STDERR responses and the +silence_stream+ allows you to also silence other streams. Additionally, this mixin allows you to suppress exceptions and capture streams. For more information see the "Silencing Warnings, Streams, and Exceptions":http://guides.rubyonrails.org/active_support_core_extensions.html#silencing-warnings-streams-and-exceptions section from the Active Support Core Extensions Guide.
@@ -635,14 +636,14 @@ h4. +railties/lib/rails/rack.rb+
The final file to be loaded by +railties/lib/rails/configuration.rb+ is +rails/rack+ which defines some simple autoloads:
<ruby>
- module Rails
- module Rack
- autoload :Debugger, "rails/rack/debugger"
- autoload :Logger, "rails/rack/logger"
- autoload :LogTailer, "rails/rack/log_tailer"
- autoload :Static, "rails/rack/static"
- end
+module Rails
+ module Rack
+ autoload :Debugger, "rails/rack/debugger"
+ autoload :Logger, "rails/rack/logger"
+ autoload :LogTailer, "rails/rack/log_tailer"
+ autoload :Static, "rails/rack/static"
end
+end
</ruby>
Once this file is finished loading, then the +Rails::Configuration+ class is initialized. This completes the loading of +railties/lib/rails/configuration.rb+ and now we jump back to the loading of +railties/lib/rails/railtie.rb+, where the next file loaded is +active_support/inflector+.
@@ -652,17 +653,17 @@ h4. +activesupport/lib/active_support/inflector.rb+
+active_support/inflector.rb+ requires a series of file which are responsible for setting up the basics for knowing how to pluralize and singularize words. These files are:
<ruby>
- require 'active_support/inflector/inflections'
- require 'active_support/inflector/transliterate'
- require 'active_support/inflector/methods'
+require 'active_support/inflector/inflections'
+require 'active_support/inflector/transliterate'
+require 'active_support/inflector/methods'
- require 'active_support/inflections'
- require 'active_support/core_ext/string/inflections'
+require 'active_support/inflections'
+require 'active_support/core_ext/string/inflections'
</ruby>
-The +active_support/inflector/methods+ file has already been required by +active_support/autoload+ and so won't be loaded again here.
+The +active_support/inflector/methods+ file has already been required by +active_support/autoload+ and so won't be loaded again here. The +activesupport/lib/active_support/inflector/inflections.rb+ is required by +active_support/inflector/methods+.
-h4. +activesupport/lib/active_support/inflector/inflections.rb+
+h4. +active_support/inflections+
This file references the +ActiveSupport::Inflector+ constant which isn't loaded by this point. But there were autoloads set up in +activesupport/lib/active_support.rb+ which will load the file which loads this constant and so then it will be defined. Then this file defines pluralization and singularization rules for words in Rails. This is how Rails knows how to pluralize "tomato" to "tomatoes".
@@ -721,22 +722,22 @@ h4. +activesupport/lib/active_support/i18n_railtie.rb+
This file is the first file that sets up configuration with these lines inside the class:
<ruby>
- class Railtie < Rails::Railtie
- config.i18n = ActiveSupport::OrderedOptions.new
- config.i18n.railties_load_path = []
- config.i18n.load_path = []
- config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
+class Railtie < Rails::Railtie
+ config.i18n = ActiveSupport::OrderedOptions.new
+ config.i18n.railties_load_path = []
+ config.i18n.load_path = []
+ config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
</ruby>
By inheriting from +Rails::Railtie+ the +Rails::Railtie#inherited+ method is called:
<ruby>
- def inherited(base)
- unless base.abstract_railtie?
- base.send(:include, Railtie::Configurable)
- subclasses << base
- end
+def inherited(base)
+ unless base.abstract_railtie?
+ base.send(:include, Railtie::Configurable)
+ subclasses << base
end
+end
</ruby>
This first checks if the Railtie that's inheriting it is a component of Rails itself:
@@ -763,15 +764,15 @@ end
The +config+ method used at the top of +I18n::Railtie+ is defined on +Rails::Railtie+ and is defined like this:
<ruby>
- def config
- @config ||= Railtie::Configuration.new
- end
+def config
+ @config ||= Railtie::Configuration.new
+end
</ruby>
At this point, that +Railtie::Configuration+ constant is automatically loaded which causes the +rails/railties/configuration+ file to be loaded. The line for this is this particular line in +railties/lib/rails/railtie.rb+:
<ruby>
- autoload :Configuration, "rails/railtie/configuration"
+autoload :Configuration, "rails/railtie/configuration"
</ruby>
h4. +railties/lib/rails/railtie/configuration.rb+
@@ -781,15 +782,15 @@ This file begins with a require out to +rails/configuration+ which has already b
This file defines the +Rails::Railtie::Configuration+ class which is responsible for providing a way to easily configure railties and it's the +initialize+ method here which is called by the +config+ method back in the +i18n_railtie.rb+ file. The methods on this object don't exist, and so are rescued by the +method_missing+ defined further down in +configuration.rb+:
<ruby>
- def method_missing(name, *args, &blk)
- if name.to_s =~ /=$/
- @@options[$`.to_sym] = args.first
- elsif @@options.key?(name)
- @@options[name]
- else
- super
- end
+def method_missing(name, *args, &blk)
+ if name.to_s =~ /=$/
+ @@options[$`.to_sym] = args.first
+ elsif @@options.key?(name)
+ @@options[name]
+ else
+ super
end
+end
</ruby>
So therefore when an option is referred to it simply stores the value as the key if it's used in a setter context, or retrieves it if used in a getter context. Nothing fancy going on there.
@@ -799,21 +800,21 @@ h4. Back to +activesupport/lib/active_support/i18n_railtie.rb+
After the configuration method the +reloader+ method is defined, and then the first of of Railties' initializers is defined: +i18n.callbacks+.
<ruby>
- initializer "i18n.callbacks" do
- ActionDispatch::Reloader.to_prepare do
- I18n::Railtie.reloader.execute_if_updated
- end
+initializer "i18n.callbacks" do
+ ActionDispatch::Reloader.to_prepare do
+ I18n::Railtie.reloader.execute_if_updated
end
+end
</ruby>
The +initializer+ method (from the +Rails::Initializable+ module) here doesn't run the block, but rather stores it to be run later on:
<ruby>
- def initializer(name, opts = {}, &blk)
- raise ArgumentError, "A block must be passed when defining an initializer" unless blk
- opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] }
- initializers << Initializer.new(name, nil, opts, &blk)
- end
+def initializer(name, opts = {}, &blk)
+ raise ArgumentError, "A block must be passed when defining an initializer" unless blk
+ opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] }
+ initializers << Initializer.new(name, nil, opts, &blk)
+end
</ruby>
An initializer can be configured to run before or after another initializer, which we'll see a couple of times throughout this initialization process. Anything that inherits from +Rails::Railtie+ may also make use of the +initializer+ method, something which is covered in the "Configuration guide":[http://ryanbigg.com/guides/configuring.html#rails-railtie-initializer].
@@ -821,25 +822,25 @@ An initializer can be configured to run before or after another initializer, whi
The +Initializer+ class here is defined within the +Rails::Initializable+ module and its +initialize+ method is defined to just set up a couple of variables:
<ruby>
- def initialize(name, context, options, &block)
- @name, @context, @options, @block = name, context, options, block
- end
+def initialize(name, context, options, &block)
+ @name, @context, @options, @block = name, context, options, block
+end
</ruby>
Once this +initialize+ method is finished, the object is added to the object the +initializers+ method returns:
<ruby>
- def initializers
- @initializers ||= self.class.initializers_for(self)
- end
+def initializers
+ @initializers ||= self.class.initializers_for(self)
+end
</ruby>
If +@initializers+ isn't set (which it won't be at this point), the +intializers_for+ method will be called for this class.
<ruby>
- def initializers_for(binding)
- Collection.new(initializers_chain.map { |i| i.bind(binding) })
- end
+def initializers_for(binding)
+ Collection.new(initializers_chain.map { |i| i.bind(binding) })
+end
</ruby>
The +Collection+ class in +railties/lib/rails/initializable.rb+ inherits from +Array+ and includes the +TSort+ module which is used to sort out the order of the initializers based on the order they are placed in.
@@ -847,57 +848,57 @@ The +Collection+ class in +railties/lib/rails/initializable.rb+ inherits from +A
The +initializers_chain+ method referenced in the +initializers_for+ method is defined like this:
<rub>
- def initializers_chain
- initializers = Collection.new
- ancestors.reverse_each do | klass |
- next unless klass.respond_to?(:initializers)
- initializers = initializers + klass.initializers
- end
- initializers
+def initializers_chain
+ initializers = Collection.new
+ ancestors.reverse_each do | klass |
+ next unless klass.respond_to?(:initializers)
+ initializers = initializers + klass.initializers
end
+ initializers
+end
</ruby>
This method collects the initializers from the ancestors of this class and adds them to a new +Collection+ object using the <tt>+</tt> method which is defined like this for the <tt>Collection</tt> class:
<ruby>
- def +(other)
- Collection.new(to_a + other.to_a)
- end
+def +(other)
+ Collection.new(to_a + other.to_a)
+end
</ruby>
-So this <tt>+</tt> method is overriden to return a new collection comprising of the existing collection as an array and then using the <tt>Array#+</tt> method combines these two collections, returning a "super" +Collection+ object. In this case, the only initializer that's going to be in this new +Collection+ object is the +i18n.callbacks+ initializer.
+So this <tt>+</tt> method is overridden to return a new collection comprising of the existing collection as an array and then using the <tt>Array#+</tt> method combines these two collections, returning a "super" +Collection+ object. In this case, the only initializer that's going to be in this new +Collection+ object is the +i18n.callbacks+ initializer.
The next method to be called after this +initializer+ method is the +after_initialize+ method on the +config+ object, which is defined like this:
<ruby>
- def after_initialize(&block)
- ActiveSupport.on_load(:after_initialize, :yield => true, &block)
- end
+def after_initialize(&block)
+ ActiveSupport.on_load(:after_initialize, :yield => true, &block)
+end
</ruby>
The +on_load+ method here is provided by the +active_support/lazy_load_hooks+ file which was required earlier and is defined like this:
<ruby>
- def self.on_load(name, options = {}, &block)
- if base = @loaded[name]
- execute_hook(base, options, block)
- else
- @load_hooks[name] << [block, options]
- end
+def self.on_load(name, options = {}, &block)
+ if base = @loaded[name]
+ execute_hook(base, options, block)
+ else
+ @load_hooks[name] << [block, options]
end
+end
</ruby>
The +@loaded+ variable here is a hash containing elements representing the different components of Rails that have been loaded at this stage. Currently, this hash is empty. So the +else+ is executed here, using the +@load_hooks+ variable defined in +active_support/lazy_load_hooks+:
<ruby>
- @load_hooks = Hash.new {|h,k| h[k] = [] }
+@load_hooks = Hash.new {|h,k| h[k] = [] }
</ruby>
This defines a new hash which has keys that default to empty arrays. This saves Rails from having to do something like this instead:
<ruby>
- @load_hooks[name] = []
- @load_hooks[name] << [block, options]
+@load_hooks[name] = []
+@load_hooks[name] << [block, options]
</ruby>
The value added to this array here consists of the block and options passed to +after_initialize+.
@@ -929,11 +930,11 @@ h4. +activesupport/lib/action_dispatch.rb+
This file attempts to locate the +active_support+ and +active_model+ libraries by looking a couple of directories back from the current file and then adds the +active_support+ and +active_model+ +lib+ directories to the load path, but only if they aren't already, which they are.
<ruby>
- activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
- $:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
+activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
+$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
- activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__)
- $:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path)
+activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__)
+$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path)
</ruby>
In effect, these lines only define the +activesupport_path+ and +activemodel_path+ variables and nothing more.
@@ -941,23 +942,23 @@ In effect, these lines only define the +activesupport_path+ and +activemodel_pat
The next two requires in this file are already done, so they are not run:
<ruby>
- require 'active_support'
- require 'active_support/dependencies/autoload'
+require 'active_support'
+require 'active_support/dependencies/autoload'
</ruby>
The following require is to +action_pack+ (+activesupport/lib/action_pack.rb+) which has a 22-line copyright notice at the top of it and ends in a simple require to +action_pack/version+. This file, like other +version.rb+ files before it, defines the +ActionPack::VERSION+ constant:
<ruby>
- module ActionPack
- module VERSION #:nodoc:
- MAJOR = 3
- MINOR = 1
- TINY = 0
- PRE = "beta"
-
- STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
- end
+module ActionPack
+ module VERSION #:nodoc:
+ MAJOR = 3
+ MINOR = 1
+ TINY = 0
+ PRE = "beta"
+
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
+end
</ruby>
Once +action_pack+ is finished, then +active_model+ is required.
@@ -967,16 +968,16 @@ h4. +activemodel/lib/active_model.rb+
This file makes a require to +active_model/version+ which defines the version for Active Model:
<ruby>
- module ActiveModel
- module VERSION #:nodoc:
- MAJOR = 3
- MINOR = 1
- TINY = 0
- PRE = "beta"
-
- STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
- end
+module ActiveModel
+ module VERSION #:nodoc:
+ MAJOR = 3
+ MINOR = 1
+ TINY = 0
+ PRE = "beta"
+
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
+end
</ruby>
Once the +version.rb+ file is loaded, the +ActiveModel+ module has its autoloaded constants defined as well as a sub-module called +ActiveModel::Serializers+ which has autoloads of its own. When the +ActiveModel+ module is closed the +active_support/i18n+ file is required.
@@ -986,15 +987,15 @@ h4. +activesupport/lib/active_support/i18n.rb+
This is where the +i18n+ gem is required and first configured:
<ruby>
- begin
- require 'i18n'
- require 'active_support/lazy_load_hooks'
- rescue LoadError => e
- $stderr.puts "You don't have i18n installed in your application. Please add it to your Gemfile and run bundle install"
- raise e
- end
+begin
+ require 'i18n'
+ require 'active_support/lazy_load_hooks'
+rescue LoadError => e
+ $stderr.puts "You don't have i18n installed in your application. Please add it to your Gemfile and run bundle install"
+ raise e
+end
- I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
+I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
</ruby>
In effect, the +I18n+ module first defined by +i18n_railtie+ is extended by the +i18n+ gem, rather than the other way around. This has no ill effect. They both work on the same way.
@@ -1012,9 +1013,9 @@ h4. Back to +activesupport/lib/action_dispatch.rb+
The remainder of this file requires the +rack+ file from the Rack gem which defines the +Rack+ module. After +rack+, there's autoloads defined for the +Rack+, +ActionDispatch+, +ActionDispatch::Http+, +ActionDispatch::Session+. A new method called +autoload_under+ is used here, and this simply prefixes the files where the modules are autoloaded from with the path specified. For example here:
<ruby>
- autoload_under 'testing' do
- autoload :Assertions
- ...
+autoload_under 'testing' do
+ autoload :Assertions
+...
</ruby>
The +Assertions+ module is in the +action_dispatch/testing+ folder rather than simply +action_dispatch+.
@@ -1046,25 +1047,25 @@ This file begins by detecting if the +lib+ directories of +active_support+ and +
The first three requires have already been done by other files and so aren't loaded here, but the 4th require, the one to +arel+ will require the file provided by the Arel gem, which defines the +Arel+ module.
<ruby>
- require 'active_support'
- require 'active_support/i18n'
- require 'active_model'
- require 'arel'
+require 'active_support'
+require 'active_support/i18n'
+require 'active_model'
+require 'arel'
</ruby>
The 5th require in this file is one to +active_record/version+ which defines the +ActiveRecord::VERSION+ constant:
<ruby>
- module ActiveRecord
- module VERSION #:nodoc:
- MAJOR = 3
- MINOR = 1
- TINY = 0
- PRE = "beta"
-
- STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
- end
+module ActiveRecord
+ module VERSION #:nodoc:
+ MAJOR = 3
+ MINOR = 1
+ TINY = 0
+ PRE = "beta"
+
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
+end
</ruby>
Once these requires are finished, the base for the +ActiveRecord+ module is defined along with its autoloads.
@@ -1072,9 +1073,9 @@ Once these requires are finished, the base for the +ActiveRecord+ module is defi
Near the end of the file, we see this line:
<ruby>
- ActiveSupport.on_load(:active_record) do
- Arel::Table.engine = self
- end
+ActiveSupport.on_load(:active_record) do
+ Arel::Table.engine = self
+end
</ruby>
This will set the engine for +Arel::Table+ to be +ActiveRecord::Base+.
@@ -1082,7 +1083,7 @@ This will set the engine for +Arel::Table+ to be +ActiveRecord::Base+.
The file then finishes with this line:
<ruby>
- I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
+I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
</ruby>
This will add the translations from +activerecord/lib/active_record/locale/en.yml+ to the load path for +I18n+, with this file being parsed when all the translations are loaded.
@@ -1092,8 +1093,8 @@ h4. Back to +activerecord/lib/active_record/railtie.rb+
The next two <tt>require</tt>s in this file aren't run because their files are already required, with +rails+ being required by +rails/all+ and +active_model/railtie+ being required from +action_dispatch+.
<ruby>
- require "rails"
- require "active_model/railtie"
+require "rails"
+require "active_model/railtie"
</ruby>
The next +require+ in this file is to +action_controller/railtie+.
@@ -1103,9 +1104,9 @@ h4. +actionpack/lib/action_controller/railtie.rb+
This file begins with a couple more requires to files that have already been loaded:
<ruby>
- require "rails"
- require "action_controller"
- require "action_dispatch/railtie"
+require "rails"
+require "action_controller"
+require "action_dispatch/railtie"
</ruby>
However the require after these is to a file that hasn't yet been loaded, +action_view/railtie+, which begins by requiring +action_view+.
diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile
index d67668df91..ba45b84242 100644
--- a/railties/guides/source/layouts_and_rendering.textile
+++ b/railties/guides/source/layouts_and_rendering.textile
@@ -123,7 +123,7 @@ Cache-Control: no-cache
$
</shell>
-We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ option on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an acknowledgement that the request was completed.
+We see there is an empty response (no data after the +Cache-Control+ line), but the request was successful because Rails has set the response to 200 OK. You can set the +:status+ option on render to change this response. Rendering nothing can be useful for AJAX requests where all you want to send back to the browser is an acknowledgment that the request was completed.
TIP: You should probably be using the +head+ method, discussed later in this guide, instead of +render :nothing+. This provides additional flexibility and makes it explicit that you're only generating HTTP headers.
diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile
index d60b68ec7f..dbbf8f3b51 100644
--- a/railties/guides/source/migrations.textile
+++ b/railties/guides/source/migrations.textile
@@ -55,6 +55,8 @@ class AddReceiveNewsletterToUsers < ActiveRecord::Migration
end
</ruby>
+NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations.
+
This migration adds a +receive_newsletter+ column to the +users+ table. We want it to default to +false+ for new users, but existing users are considered
to have already opted in, so we use the User model to set the flag to +true+ for existing users.
@@ -73,11 +75,9 @@ class CreateProducts < ActiveRecord::Migration
end
</ruby>
-NOTE: Some "caveats":#using-models-in-your-migrations apply to using models in your migrations.
-
h4. Migrations are Classes
-A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements two class methods: +up+ (perform the required transformations) and +down+ (revert them).
+A migration is a subclass of <tt>ActiveRecord::Migration</tt> that implements two methods: +up+ (perform the required transformations) and +down+ (revert them).
Active Record provides methods that perform common data definition tasks in a database independent way (you'll read about them in detail later):
@@ -115,7 +115,7 @@ h4. Changing Migrations
Occasionally you will make a mistake when writing a migration. If you have already run the migration then you cannot just edit the migration and run the migration again: Rails thinks it has already run the migration and so will do nothing when you run +rake db:migrate+. You must rollback the migration (for example with +rake db:rollback+), edit your migration and then run +rake db:migrate+ to run the corrected version.
-In general editing existing migrations is not a good idea: you will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or more generally which has not been propagated beyond your development machine) is relatively harmless. Just use some common sense.
+In general editing existing migrations is not a good idea: you will be creating extra work for yourself and your co-workers and cause major headaches if the existing version of the migration has already been run on production machines. Instead you should write a new migration that performs the changes you require. Editing a freshly generated migration that has not yet been committed to source control (or more generally which has not been propagated beyond your development machine) is relatively harmless.
h3. Creating a Migration
@@ -344,7 +344,7 @@ The +change+ method removes the need to write both +up+ and +down+ methods in th
* +add_column+
* +add_index+
-* +add_timestamp+
+* +add_timestamps+
* +create_table+
* +remove_timestamps+
* +rename_column+
diff --git a/railties/guides/source/nested_model_forms.textile b/railties/guides/source/nested_model_forms.textile
index 55694c0eb4..4b1fd2e0ac 100644
--- a/railties/guides/source/nested_model_forms.textile
+++ b/railties/guides/source/nested_model_forms.textile
@@ -90,7 +90,7 @@ h3. Views
h4. Controller code
-A nested model form will _only_ be build if the associated object(s) exist. This means that for a new model instance you would probably want to build the associated object(s) first.
+A nested model form will _only_ be built if the associated object(s) exist. This means that for a new model instance you would probably want to build the associated object(s) first.
Consider the following typical RESTful controller which will prepare a new Person instance and its +address+ and +projects+ associations before rendering the +new+ template:
@@ -144,7 +144,7 @@ Now add a nested form for the +address+ association:
<%= f.text_field :name %>
<%= f.fields_for :address do |af| %>
- <%= f.text_field :street %>
+ <%= af.text_field :street %>
<% end %>
<% end %>
</erb>
@@ -159,7 +159,7 @@ This generates:
</form>
</html>
-Notice that +fields_for+ recognized the +address+ as an association for which a nested model form should be build by the way it has namespaced the +name+ attribute.
+Notice that +fields_for+ recognized the +address+ as an association for which a nested model form should be built by the way it has namespaced the +name+ attribute.
When this form is posted the Rails parameter parser will construct a hash like the following:
@@ -185,7 +185,7 @@ The form code for an association collection is pretty similar to that of a singl
<%= f.text_field :name %>
<%= f.fields_for :projects do |pf| %>
- <%= f.text_field :name %>
+ <%= pf.text_field :name %>
<% end %>
<% end %>
</erb>
@@ -201,7 +201,7 @@ Which generates:
</form>
</html>
-As you can see it has generated 2 +project name+ inputs, one for each new +project+ that’s build in the controllers +new+ action. Only this time the +name+ attribute of the input contains a digit as an extra namespace. This will be parsed by the Rails parameter parser as:
+As you can see it has generated 2 +project name+ inputs, one for each new +project+ that was built in the controller's +new+ action. Only this time the +name+ attribute of the input contains a digit as an extra namespace. This will be parsed by the Rails parameter parser as:
<ruby>
{
@@ -215,7 +215,7 @@ As you can see it has generated 2 +project name+ inputs, one for each new +proje
}
</ruby>
-You can basically see the +projects_attributes+ hash as an array of attribute hashes. One for each model instance.
+You can basically see the +projects_attributes+ hash as an array of attribute hashes, one for each model instance.
NOTE: The reason that +fields_for+ constructed a form which would result in a hash instead of an array is that it won't work for any forms nested deeper than one level deep.
diff --git a/railties/guides/source/performance_testing.textile b/railties/guides/source/performance_testing.textile
index 2b79237c59..dbe6f97f5c 100644
--- a/railties/guides/source/performance_testing.textile
+++ b/railties/guides/source/performance_testing.textile
@@ -66,7 +66,7 @@ resources :posts
# home_controller.rb
class HomeController < ApplicationController
def dashboard
- @users = User.last_ten(:include => :avatars)
+ @users = User.last_ten.includes(:avatars)
@posts = Post.all_today
end
end
@@ -151,7 +151,7 @@ Performance tests can be run in two modes: Benchmarking and Profiling.
h5. Benchmarking
-Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run +4 times+ in benchmarking mode.
+Benchmarking makes it easy to quickly gather a few metrics about each test tun. By default, each test case is run *4 times* in benchmarking mode.
To run performance tests in benchmarking mode:
@@ -161,7 +161,7 @@ $ rake test:benchmark
h5. Profiling
-Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run +1 time+ in profiling mode.
+Profiling allows you to make an in-depth analysis of each of your tests by using an external profiler. Depending on your Ruby interpreter, this profiler can be native (Rubinius, JRuby) or not (MRI, which uses RubyProf). By default, each test case is run *once* in profiling mode.
To run performance tests in profiling mode:
@@ -276,7 +276,7 @@ measurement,created_at,app,rails,ruby,platform
h5(#output-profiling). Profiling
-In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is dependant on the interpreter in use. A brief description of each type and their availability across interpreters is given below.
+In profiling mode, performance tests can generate multiple types of outputs. The command line output is always presented but support for the others is dependent on the interpreter in use. A brief description of each type and their availability across interpreters is given below.
h6. Command Line
@@ -481,7 +481,7 @@ h4. +profiler+
Usage:
<shell>
-Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]
+Usage: rails profiler 'Ruby.code' 'Ruby.more_code' ... [OPTS]
-r, --runs N Number of runs.
Default: 1
-o, --output PATH Directory to use when writing the results.
@@ -573,7 +573,7 @@ h3. Useful Links
h4. Rails Plugins and Gems
* "Rails Analyzer":http://rails-analyzer.rubyforge.org
-* "Palmist":http://www.flyingmachinestudios.com/projects/
+* "Palmist":http://www.flyingmachinestudios.com/programming/announcing-palmist
* "Rails Footnotes":https://github.com/josevalim/rails-footnotes/tree/master
* "Query Reviewer":https://github.com/dsboulder/query_reviewer/tree/master
diff --git a/railties/guides/source/plugins.textile b/railties/guides/source/plugins.textile
index d486e8ade3..79bbe495bd 100644
--- a/railties/guides/source/plugins.textile
+++ b/railties/guides/source/plugins.textile
@@ -25,33 +25,36 @@ endprologue.
h3. Setup
-h4. Generating the Plugin Skeleton
+Before you continue, take a moment to decide if your new plugin will be potentially shared across different Rails applications.
-Rails currently ships with a generator to generate a plugin within a Rails application. Help text is available that will explain
-how this generator works.
+* If your plugin is specific to your application, your new plugin will be a _vendored plugin_.
+* If you think your plugin may be used across applications, build it as a _gemified plugin_.
+
+h4. Either generate a vendored plugin...
+
+Use the +rails generate plugin+ command in your Rails root directory
+ to create a new plugin that will live in the +vendor/plugins+
+ directory. See usage and options by asking for help:
<shell>
$ rails generate plugin --help
</shell>
-This generator places the plugin into the vendor/plugins directory.
+h4. Or generate a gemified plugin.
-Vendored plugins are useful for quickly prototyping your plugin but current thinking in the Rails community is shifting towards
-packaging plugins as gems, especially with the inclusion of Bundler as the Rails dependency manager.
-Packaging a plugin as a gem may be overkill for any plugins that will not be shared across projects but doing so from the start makes it easier to share the plugin going forward without adding too much additional overhead during development.
+Writing your Rails plugin as a gem, rather than as a vendored plugin,
+ lets you share your plugin across different rails applications using
+ RubyGems and Bundler.
-Rails 3.1 will ship with a plugin generator that will default to setting up a plugin
-as a gem. This tutorial will begin to bridge that gap by demonstrating how to create a gem based plugin using the
-"Enginex gem":http://www.github.com/josevalim/enginex.
+Rails 3.1 ships with a +rails plugin new+ command which creates a
+ skeleton for developing any kind of Rails extension with the ability
+ to run integration tests using a dummy Rails application. See usage
+ and options by asking for help:
<shell>
-$ gem install enginex
-$ enginex --help
-$ enginex yaffle
+$ rails plugin --help
</shell>
-This command will create a new directory named "yaffle" within the current directory.
-
h3. Testing your newly generated plugin
You can navigate to the directory that contains the plugin, run the +bundle install+ command
@@ -319,7 +322,7 @@ When you run +rake+ you should see the tests all pass:
h4. Add an Instance Method
-This plugin will add a method named 'squawk' to any Active Record objects that call 'acts_as_yaffle'. The 'squawk'
+This plugin will add a method named 'squawk' to any Active Record objects that call 'acts_as_yaffle'. The 'squawk'
method will simply set the value of one of the fields in the database.
To start out, write a failing test that shows the behavior you'd like:
@@ -387,9 +390,7 @@ Run +rake+ one final time and you should see:
7 tests, 7 assertions, 0 failures, 0 errors, 0 skips
</shell>
-NOTE: The use of +write_attribute+ to write to the field in model is just one example of how a plugin can
-interact with the model, and will not always be the right method to use. For example, you could also
-use +send("#{self.class.yaffle_text_field}=", string.to_squawk)+.
+NOTE: The use of +write_attribute+ to write to the field in model is just one example of how a plugin can interact with the model, and will not always be the right method to use. For example, you could also use <tt>send("#{self.class.yaffle_text_field}=", string.to_squawk)</tt>.
h3. Generators
diff --git a/railties/guides/source/rails_application_templates.textile b/railties/guides/source/rails_application_templates.textile
index 388d8eea3e..3db47a70e8 100644
--- a/railties/guides/source/rails_application_templates.textile
+++ b/railties/guides/source/rails_application_templates.textile
@@ -1,6 +1,6 @@
h2. Rails Application Templates
-Application templates are simple ruby files containing DSL for adding plugins/gems/initializers etc. to your freshly created Rails project or an existing Rails project.
+Application templates are simple Ruby files containing DSL for adding plugins/gems/initializers etc. to your freshly created Rails project or an existing Rails project.
By referring to this guide, you will be able to:
@@ -58,14 +58,12 @@ gem "bj"
gem "nokogiri"
</ruby>
-Please note that this will NOT install the gems for you. So you may want to run the +rake gems:install+ task too:
+Please note that this will NOT install the gems for you and you will have to run +bundle install+ to do that.
<ruby>
-rake "gems:install"
+bundle install
</ruby>
-And let Rails take care of installing the required gems if they’re not already installed.
-
h4. add_source(source, options = {})
Adds the given source to the generated application's +Gemfile+.
@@ -229,7 +227,7 @@ rake("rails:freeze:gems") if yes?("Freeze rails gems ?")
no?(question) acts just the opposite.
</ruby>
-h4. git(:must => "-a love")
+h4. git(:command)
Rails templates let you run any git command:
diff --git a/railties/guides/source/rails_on_rack.textile b/railties/guides/source/rails_on_rack.textile
index aa53aa6db6..8d5985dba8 100644
--- a/railties/guides/source/rails_on_rack.textile
+++ b/railties/guides/source/rails_on_rack.textile
@@ -111,11 +111,11 @@ h5. Adding a Middleware
You can add a new middleware to the middleware stack using any of the following methods:
-* +config.middleware.use(new_middleware, args)+ - Adds the new middleware at the bottom of the middleware stack.
+* <tt>config.middleware.use(new_middleware, args)</tt> - Adds the new middleware at the bottom of the middleware stack.
-* +config.middleware.insert_before(existing_middleware, new_middleware, args)+ - Adds the new middleware before the specified existing middleware in the middleware stack.
+* <tt>config.middleware.insert_before(existing_middleware, new_middleware, args)</tt> - Adds the new middleware before the specified existing middleware in the middleware stack.
-* +config.middleware.insert_after(existing_middleware, new_middleware, args)+ - Adds the new middleware after the specified existing middleware in the middleware stack.
+* <tt>config.middleware.insert_after(existing_middleware, new_middleware, args)</tt> - Adds the new middleware after the specified existing middleware in the middleware stack.
<ruby>
# config/environment.rb
@@ -154,20 +154,20 @@ h4. Internal Middleware Stack
Much of Action Controller's functionality is implemented as Middlewares. The following table explains the purpose of each of them:
|_.Middleware|_.Purpose|
-|+Rack::Lock+|Sets +env["rack.multithread"]+ flag to +true+ and wraps the application within a Mutex.|
+|+Rack::Lock+|Sets <tt>env["rack.multithread"]</tt> flag to +true+ and wraps the application within a Mutex.|
|+ActionController::Failsafe+|Returns HTTP Status +500+ to the client if an exception gets raised while dispatching.|
|+ActiveRecord::QueryCache+|Enables the Active Record query cache.|
|+ActionController::Session::CookieStore+|Uses the cookie based session store.|
|+ActionController::Session::MemCacheStore+|Uses the memcached based session store.|
|+ActiveRecord::SessionStore+|Uses the database based session store.|
-|+Rack::MethodOverride+|Sets HTTP method based on +_method+ parameter or +env["HTTP_X_HTTP_METHOD_OVERRIDE"]+.|
+|+Rack::MethodOverride+|Sets HTTP method based on +_method+ parameter or <tt>env["HTTP_X_HTTP_METHOD_OVERRIDE"]</tt>.|
|+Rack::Head+|Discards the response body if the client sends a +HEAD+ request.|
TIP: It's possible to use any of the above middlewares in your custom Rack stack.
h4. Customizing Internal Middleware Stack
-It's possible to replace the entire middleware stack with a custom stack using +ActionController::Dispatcher.middleware=+.
+It's possible to replace the entire middleware stack with a custom stack using <tt>ActionController::Dispatcher.middleware=</tt>.
Put the following in an initializer:
diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile
index 99fdcee68a..1cbc5c8f6e 100644
--- a/railties/guides/source/routing.textile
+++ b/railties/guides/source/routing.textile
@@ -288,7 +288,7 @@ When using +magazine_ad_path+, you can pass in instances of +Magazine+ and +Ad+
You can also use +url_for+ with a set of objects, and Rails will automatically determine which route you want:
<erb>
-<%= link_to "Ad details", url_for(@magazine, @ad) %>
+<%= link_to "Ad details", url_for([@magazine, @ad]) %>
</erb>
In this case, Rails will see that +@magazine+ is a +Magazine+ and +@ad+ is an +Ad+ and will therefore use the +magazine_ad_path+ helper. In helpers like +link_to+, you can specify just the object in place of the full +url_for+ call:
@@ -880,7 +880,7 @@ h3. Changelog
* April 10, 2010: Updated guide to remove outdated and superfluous information, and to provide information about new features, by "Yehuda Katz":http://www.yehudakatz.com
* April 2, 2010: Updated guide to match new Routing DSL in Rails 3, by "Rizwan Reza":http://www.rizwanreza.com/
-* Febuary 1, 2010: Modifies the routing documentation to match new routing DSL in Rails 3, by Prem Sichanugrist
+* February 1, 2010: Modifies the routing documentation to match new routing DSL in Rails 3, by Prem Sichanugrist
* October 4, 2008: Added additional detail on specifying verbs for resource member/collection routes, by "Mike Gunderloy":credits.html#mgunderloy
* September 23, 2008: Added section on namespaced controllers and routing, by "Mike Gunderloy":credits.html#mgunderloy
* September 10, 2008: initial version by "Mike Gunderloy":credits.html#mgunderloy
diff --git a/railties/guides/source/ruby_on_rails_guides_guidelines.textile b/railties/guides/source/ruby_on_rails_guides_guidelines.textile
index 26a5a4c3c9..5989191b5c 100644
--- a/railties/guides/source/ruby_on_rails_guides_guidelines.textile
+++ b/railties/guides/source/ruby_on_rails_guides_guidelines.textile
@@ -62,10 +62,10 @@ To force process of all the guides, pass +ALL=1+.
It is also recommended that you work with +WARNINGS=1+. This detects duplicate IDs and warns about broken internal links.
-If you want to generate guides in languages other than English, you can keep them in a separate directory under +source+ (eg. <tt>source/es</tt>) and use the +LANGUAGE+ environment variable:
+If you want to generate guides in languages other than English, you can keep them in a separate directory under +source+ (eg. <tt>source/es</tt>) and use the +GUIDES_LANGUAGE+ environment variable:
<plain>
-rake generate_guides LANGUAGE=es
+bundle exec rake generate_guides GUIDES_LANGUAGE=es
</plain>
h3. HTML Validation
@@ -73,7 +73,7 @@ h3. HTML Validation
Please validate the generated HTML with:
<plain>
-rake validate_guides
+bundle exec rake validate_guides
</plain>
Particularly, titles get an ID generated from their content and this often leads to duplicates. Please set +WARNINGS=1+ when generating guides to detect them. The warning messages suggest a way to fix them.
diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile
index e0ccc7a6e6..908f3f125a 100644
--- a/railties/guides/source/security.textile
+++ b/railties/guides/source/security.textile
@@ -386,7 +386,7 @@ params[:user] # => {:name => “ow3ned”, :admin => true}
So if you create a new user using mass-assignment, it may be too easy to become an administrator.
-Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3+. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example:
+Note that this vulnerability is not restricted to database columns. Any setter method, unless explicitly protected, is accessible via the <tt>attributes=</tt> method. In fact, this vulnerability is extended even further with the introduction of nested mass assignment (and nested object forms) in Rails 2.3+. The +accepts_nested_attributes_for+ declaration provides us the ability to extend mass assignment to model associations (+has_many+, +has_one+, +has_and_belongs_to_many+). For example:
<ruby>
class Person < ActiveRecord::Base
@@ -469,7 +469,7 @@ A more paranoid technique to protect your whole project would be to enforce that
config.active_record.whitelist_attributes = true
</ruby>
-This will create an empty whitelist of attributes available for mass-assignment for all models in your app. As such, your models will need to explicitly whitelist or blacklist accessible parameters by using an +attr_accessible+ or +attr_protected+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to use this application config option; run your tests, and expose each attribute (via +attr_accessible+ or +attr_protected+) as dictated by your failing tests.
+This will create an empty whitelist of attributes available for mass-assignment for all models in your app. As such, your models will need to explicitly whitelist or blacklist accessible parameters by using an +attr_accessible+ or +attr_protected+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to use this application config option; run your tests, and expose each attribute (via +attr_accessible+ or +attr_protected+) as dictated by your failing tests.
h3. User Management
@@ -540,7 +540,7 @@ Most bots are really dumb, they crawl the web and put their spam into every form
Here are some ideas how to hide honeypot fields by JavaScript and/or CSS:
* position the fields off of the visible area of the page
-* make the elements very small or colour them the same as the background of the page
+* make the elements very small or color them the same as the background of the page
* leave the fields displayed, but tell humans to leave them blank
The most simple negative CAPTCHA is one hidden honeypot field. On the server side, you will check the value of the field: If it contains any text, it must be a bot. Then, you can either ignore the post or return a positive result, but not saving the post to the database. This way the bot will be satisfied and moves on. You can do this with annoying users, too.
@@ -567,7 +567,7 @@ h4. Good Passwords
-- _Do you find it hard to remember all your passwords? Don't write them down, but use the initial letters of each word in an easy to remember sentence._
-Bruce Schneier, a security technologist, "has analysed":http://www.schneier.com/blog/archives/2006/12/realworld_passw.html 34,000 real-world user names and passwords from the MySpace phishing attack mentioned <a href="#examples-from-the-underground">below</a>. It turns out that most of the passwords are quite easy to crack. The 20 most common passwords are:
+Bruce Schneier, a security technologist, "has analyzed":http://www.schneier.com/blog/archives/2006/12/realworld_passw.html 34,000 real-world user names and passwords from the MySpace phishing attack mentioned <a href="#examples-from-the-underground">below</a>. It turns out that most of the passwords are quite easy to crack. The 20 most common passwords are:
password1, abc123, myspace1, password, blink182, qwerty1, ****you, 123abc, baseball1, football1, 123456, soccer, monkey1, liverpool1, princess1, jordan23, slipknot1, superman1, iloveyou1, and monkey.
@@ -649,7 +649,7 @@ h5(#sql-injection-introduction). Introduction
SQL injection attacks aim at influencing database queries by manipulating web application parameters. A popular goal of SQL injection attacks is to bypass authorization. Another goal is to carry out data manipulation or reading arbitrary data. Here is an example of how not to use user input data in a query:
<ruby>
-Project.all(:conditions => "name = '#{params[:name]}'")
+Project.where("name = '#{params[:name]}'")
</ruby>
This could be in a search action and the user may enter a project's name that he wants to find. If a malicious user enters ' OR 1 --, the resulting SQL query will be:
@@ -681,7 +681,7 @@ h5. Unauthorized Reading
The UNION statement connects two SQL queries and returns the data in one set. An attacker can use it to read arbitrary data from the database. Let's take the example from above:
<ruby>
-Project.all(:conditions => "name = '#{params[:name]}'")
+Project.where("name = '#{params[:name]}'")
</ruby>
And now let's inject another query using the UNION statement:
@@ -703,18 +703,18 @@ Also, the second query renames some columns with the AS statement so that the we
h5(#sql-injection-countermeasures). Countermeasures
-Ruby on Rails has a built-in filter for special SQL characters, which will escape ' , " , NULL character and line breaks. <em class="highlight">Using +Model.find(id)+ or +Model.find_by_some thing(something)+ automatically applies this countermeasure</em>. But in SQL fragments, especially <em class="highlight">in conditions fragments (+:conditions => "..."+), the +connection.execute()+ or +Model.find_by_sql()+ methods, it has to be applied manually</em>.
+Ruby on Rails has a built-in filter for special SQL characters, which will escape ' , " , NULL character and line breaks. <em class="highlight">Using +Model.find(id)+ or +Model.find_by_some thing(something)+ automatically applies this countermeasure</em>. But in SQL fragments, especially <em class="highlight">in conditions fragments (+where("...")+), the +connection.execute()+ or +Model.find_by_sql()+ methods, it has to be applied manually</em>.
Instead of passing a string to the conditions option, you can pass an array to sanitize tainted strings like this:
<ruby>
-Model.first(:conditions => ["login = ? AND password = ?", entered_user_name, entered_password])
+Model.where("login = ? AND password = ?", entered_user_name, entered_password).first
</ruby>
As you can see, the first part of the array is an SQL fragment with question marks. The sanitized versions of the variables in the second part of the array replace the question marks. Or you can pass a hash for the same result:
<ruby>
-Model.first(:conditions => {:login => entered_user_name, :password => entered_password})
+Model.where(:login => entered_user_name, :password => entered_password).first
</ruby>
The array or hash form is only available in model instances. You can try +sanitize_sql()+ elsewhere. _(highlight)Make it a habit to think about the security consequences when using an external string in SQL_.
@@ -885,7 +885,7 @@ The "moz-binding":http://www.securiteam.com/securitynews/5LP051FHPE.html CSS pro
h5(#css-injection-countermeasures). Countermeasures
-This example, again, showed that a blacklist filter is never complete. However, as custom CSS in web applications is a quite rare feature, I am not aware of a whitelist CSS filter. _(highlight)If you want to allow custom colours or images, you can allow the user to choose them and build the CSS in the web application_. Use Rails' +sanitize()+ method as a model for a whitelist CSS filter, if you really need one.
+This example, again, showed that a blacklist filter is never complete. However, as custom CSS in web applications is a quite rare feature, I am not aware of a whitelist CSS filter. _(highlight)If you want to allow custom colors or images, you can allow the user to choose them and build the CSS in the web application_. Use Rails' +sanitize()+ method as a model for a whitelist CSS filter, if you really need one.
h4. Textile Injection
diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile
index 7a93c3a1e6..cc55d1f756 100644
--- a/railties/guides/source/testing.textile
+++ b/railties/guides/source/testing.textile
@@ -929,8 +929,8 @@ class UserControllerTest < ActionController::TestCase
end
invite_email = ActionMailer::Base.deliveries.first
- assert_equal invite_email.subject, "You have been invited by me@example.com"
- assert_equal invite_email.to[0], 'friend@example.com'
+ assert_equal "You have been invited by me@example.com", invite_email.subject
+ assert_equal 'friend@example.com', invite_email.to[0]
assert_match /Hi friend@example.com/, invite_email.body
end
end
@@ -944,7 +944,7 @@ The built-in +test/unit+ based testing is not the only way to test Rails applica
* "Factory Girl":https://github.com/thoughtbot/factory_girl/tree/master, a replacement for fixtures.
* "Machinist":https://github.com/notahat/machinist/tree/master, another replacement for fixtures.
* "Shoulda":http://www.thoughtbot.com/projects/shoulda, an extension to +test/unit+ with additional helpers, macros, and assertions.
-* "RSpec":http://rspec.info/, a behavior-driven development framework
+* "RSpec":http://relishapp.com/rspec, a behavior-driven development framework
h3. Changelog
diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb
index cca0891835..603ede3d1e 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -4,6 +4,7 @@ require 'pathname'
require 'active_support'
require 'active_support/core_ext/kernel/reporting'
+require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/logger'
require 'rails/application'
@@ -87,6 +88,31 @@ module Rails
RAILS_CACHE
end
+ # Returns all rails groups for loading based on:
+ #
+ # * The Rails environment;
+ # * The environment variable RAILS_GROUPS;
+ # * The optional envs given as argument and the hash with group dependencies;
+ #
+ # == Examples
+ #
+ # groups :assets => [:development, :test]
+ #
+ # # Returns
+ # # => [:default, :development, :assets] for Rails.env == "development"
+ # # => [:default, :production] for Rails.env == "production"
+ #
+ def groups(*groups)
+ hash = groups.extract_options!
+ env = Rails.env
+ groups.unshift(:default, env)
+ groups.concat ENV["RAILS_GROUPS"].to_s.split(",")
+ groups.concat hash.map { |k,v| k if v.map(&:to_s).include?(env) }
+ groups.compact!
+ groups.uniq!
+ groups
+ end
+
def version
VERSION::STRING
end
diff --git a/railties/lib/rails/all.rb b/railties/lib/rails/all.rb
index 82775b7e3b..01ceb80972 100644
--- a/railties/lib/rails/all.rb
+++ b/railties/lib/rails/all.rb
@@ -6,6 +6,7 @@ require "rails"
action_mailer
active_resource
rails/test_unit
+ sprockets
).each do |framework|
begin
require "#{framework}/railtie"
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 953233d774..559739b2ec 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -78,10 +78,6 @@ module Rails
require environment if environment
end
- def eager_load! #:nodoc:
- railties.all(&:eager_load!)
- super
- end
def reload_routes!
routes_reloader.reload!
@@ -100,26 +96,25 @@ module Rails
def load_tasks(app=self)
initialize_tasks
- railties.all { |r| r.load_tasks(app) }
- super
- self
- end
-
- def load_generators(app=self)
- initialize_generators
- railties.all { |r| r.load_generators(app) }
- Rails::Generators.configure!(app.config.generators)
super
self
end
def load_console(app=self)
initialize_console
- railties.all { |r| r.load_console(app) }
super
self
end
+ # Rails.application.env_config stores some of the Rails initial environment parameters.
+ # Currently stores:
+ #
+ # * action_dispatch.parameter_filter" => config.filter_parameters,
+ # * action_dispatch.secret_token" => config.secret_token,
+ # * action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions
+ #
+ # These parameters will be used by middlewares and engines to configure themselves.
+ #
def env_config
@env_config ||= super.merge({
"action_dispatch.parameter_filter" => config.filter_parameters,
@@ -138,6 +133,10 @@ module Rails
@config ||= Application::Configuration.new(find_root_with_flag("config.ru", Dir.pwd))
end
+ def to_app
+ self
+ end
+
protected
alias :build_middleware_stack :app
@@ -195,10 +194,6 @@ module Rails
end
end
- def initialize_generators
- require "rails/generators"
- end
-
def initialize_console
require "pp"
require "rails/console/app"
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 3b74de690a..1a29483a73 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -34,7 +34,7 @@ module Rails
@assets = ActiveSupport::OrderedOptions.new
@assets.enabled = false
@assets.paths = []
- @assets.precompile = [ /\w+\.(?!js|css).+/, "application.js", "application.css" ]
+ @assets.precompile = [ /\w+\.(?!js|css).+/, /application.(css|js)$/ ]
@assets.prefix = "/assets"
@assets.js_compressor = nil
diff --git a/railties/lib/rails/application/railties.rb b/railties/lib/rails/application/railties.rb
index 4fc5e92837..8f3a3e8bbb 100644
--- a/railties/lib/rails/application/railties.rb
+++ b/railties/lib/rails/application/railties.rb
@@ -4,7 +4,7 @@ module Rails
class Application < Engine
class Railties < Rails::Engine::Railties
def all(&block)
- @all ||= railties + engines + super
+ @all ||= railties + engines + plugins
@all.each(&block) if block
@all
end
diff --git a/railties/lib/rails/code_statistics.rb b/railties/lib/rails/code_statistics.rb
index 40416dd83a..770c23ae41 100644
--- a/railties/lib/rails/code_statistics.rb
+++ b/railties/lib/rails/code_statistics.rb
@@ -104,4 +104,4 @@ class CodeStatistics #:nodoc:
puts " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f/code)}"
puts ""
end
- end
+end
diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb
index 39627a3094..5e55aeada9 100644
--- a/railties/lib/rails/commands.rb
+++ b/railties/lib/rails/commands.rb
@@ -23,11 +23,7 @@ when 'generate', 'destroy', 'plugin'
require APP_PATH
Rails.application.require_environment!
- if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH)
- Rails.application.load_generators(engine)
- else
- Rails.application.load_generators
- end
+ Rails.application.load_generators
require "rails/commands/#{command}"
end
@@ -95,7 +91,7 @@ In addition to those, there are:
benchmarker See how fast a piece of code runs
profiler Get profile information from a piece of code
plugin Install a plugin
- runner Run a piece of code in the application environment
+ runner Run a piece of code in the application environment (short-cut alias: "r")
All commands can be run with -h for more information.
EOT
diff --git a/railties/lib/rails/commands/benchmarker.rb b/railties/lib/rails/commands/benchmarker.rb
index b06c915ac3..6c52d0f70f 100644
--- a/railties/lib/rails/commands/benchmarker.rb
+++ b/railties/lib/rails/commands/benchmarker.rb
@@ -9,7 +9,7 @@ ARGV.pop
def options
options = {}
defaults = ActiveSupport::Testing::Performance::DEFAULTS
-
+
OptionParser.new do |opt|
opt.banner = "Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]"
opt.on('-r', '--runs N', Numeric, 'Number of runs.', "Default: #{defaults[:runs]}") { |r| options[:runs] = r }
@@ -17,13 +17,13 @@ def options
opt.on('-m', '--metrics a,b,c', Array, 'Metrics to use.', "Default: #{defaults[:metrics].join(",")}") { |m| options[:metrics] = m.map(&:to_sym) }
opt.parse!(ARGV)
end
-
+
options
end
class BenchmarkerTest < ActionDispatch::PerformanceTest
self.profile_options = options
-
+
ARGV.each do |expression|
eval <<-RUBY
def test_#{expression.parameterize('_')}
diff --git a/railties/lib/rails/commands/generate.rb b/railties/lib/rails/commands/generate.rb
index b6f9a003d1..1fb2d98834 100644
--- a/railties/lib/rails/commands/generate.rb
+++ b/railties/lib/rails/commands/generate.rb
@@ -7,4 +7,6 @@ if ARGV.first.in?([nil, "-h", "--help"])
end
name = ARGV.shift
-Rails::Generators.invoke name, ARGV, :behavior => :invoke, :destination_root => Rails.root
+
+root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
+Rails::Generators.invoke name, ARGV, :behavior => :invoke, :destination_root => root
diff --git a/railties/lib/rails/commands/plugin.rb b/railties/lib/rails/commands/plugin.rb
index 048af7cbef..4df849447d 100644
--- a/railties/lib/rails/commands/plugin.rb
+++ b/railties/lib/rails/commands/plugin.rb
@@ -313,11 +313,11 @@ module Commands
o.separator ""
o.separator "EXAMPLES"
o.separator " Install a plugin from a subversion URL:"
- o.separator " #{@script_name} plugin install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder\n"
+ o.separator " #{@script_name} plugin install http://example.com/my_svn_plugin\n"
o.separator " Install a plugin from a git URL:"
o.separator " #{@script_name} plugin install git://github.com/SomeGuy/my_awesome_plugin.git\n"
o.separator " Install a plugin and add a svn:externals entry to vendor/plugins"
- o.separator " #{@script_name} plugin install -x continuous_builder\n"
+ o.separator " #{@script_name} plugin install -x my_svn_plugin\n"
end
end
diff --git a/railties/lib/rails/commands/profiler.rb b/railties/lib/rails/commands/profiler.rb
index 94cf32d32d..ea6347c918 100644
--- a/railties/lib/rails/commands/profiler.rb
+++ b/railties/lib/rails/commands/profiler.rb
@@ -6,7 +6,7 @@ require 'active_support/testing/performance'
def options
options = {}
defaults = ActiveSupport::Testing::Performance::DEFAULTS
-
+
OptionParser.new do |opt|
opt.banner = "Usage: rails benchmarker 'Ruby.code' 'Ruby.more_code' ... [OPTS]"
opt.on('-r', '--runs N', Numeric, 'Number of runs.', "Default: #{defaults[:runs]}") { |r| options[:runs] = r }
@@ -15,13 +15,13 @@ def options
opt.on('-f', '--formats x,y,z', Array, 'Formats to output to.', "Default: #{defaults[:formats].join(",")}") { |m| options[:formats] = m.map(&:to_sym) }
opt.parse!(ARGV)
end
-
+
options
end
class ProfilerTest < ActionDispatch::PerformanceTest
self.profile_options = options
-
+
ARGV.each do |expression|
eval <<-RUBY
def test_#{expression.parameterize('_')}
diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb
index f8b00e7249..e8cc5d9e3b 100644
--- a/railties/lib/rails/commands/runner.rb
+++ b/railties/lib/rails/commands/runner.rb
@@ -4,6 +4,10 @@ require 'rbconfig'
options = { :environment => (ENV['RAILS_ENV'] || "development").dup }
code_or_file = nil
+if ARGV.first.nil?
+ ARGV.push "-h"
+end
+
ARGV.clone.options do |opts|
script_name = File.basename($0)
opts.banner = "Usage: runner [options] ('Some.ruby(code)' or a filename)"
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 91c87514cf..23392276d5 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -43,7 +43,7 @@ module Rails
end
def app
- @app ||= super.instance
+ @app ||= super.respond_to?(:to_app) ? super.to_app : super
end
def opt_parser
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 0d01a818f5..eb6fcd5dd7 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -180,7 +180,7 @@ module Rails
# <tt>my_engine:install:assets</tt>
#
# Engine name is set by default based on class name. For <tt>MyEngine::Engine</tt> it will be
- # <tt>my_engine_engine</tt>. You can change it manually it manually using the <tt>engine_name</tt> method:
+ # <tt>my_engine_engine</tt>. You can change it manually using the <tt>engine_name</tt> method:
#
# module MyEngine
# class Engine < Rails::Engine
@@ -296,7 +296,7 @@ module Rails
# helper MyEngine::SharedEngineHelper
# end
#
- # If you want to include all of the engine's helpers, you can use #helpers method on egine's
+ # If you want to include all of the engine's helpers, you can use #helpers method on an engine's
# instance:
#
# class ApplicationController < ActionController::Base
@@ -305,7 +305,7 @@ module Rails
#
# It will include all of the helpers from engine's directory. Take into account that this does
# not include helpers defined in controllers with helper_method or other similar solutions,
- # only helpers defined in helpers directory will be included.
+ # only helpers defined in the helpers directory will be included.
#
# == Migrations & seed data
#
@@ -330,6 +330,14 @@ module Rails
autoload :Configuration, "rails/engine/configuration"
autoload :Railties, "rails/engine/railties"
+ def load_generators(app=self)
+ initialize_generators
+ railties.all { |r| r.load_generators(app) }
+ Rails::Generators.configure!(app.config.generators)
+ super
+ self
+ end
+
class << self
attr_accessor :called_from, :isolated
alias :isolated? :isolated
@@ -387,12 +395,20 @@ module Rails
delegate :middleware, :root, :paths, :to => :config
delegate :engine_name, :isolated?, :to => "self.class"
- def load_tasks(*)
+ def load_tasks(app=self)
+ railties.all { |r| r.load_tasks(app) }
super
paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
end
-
+
+ def load_console(app=self)
+ railties.all { |r| r.load_console(app) }
+ super
+ end
+
def eager_load!
+ railties.all(&:eager_load!)
+
config.eager_load_paths.each do |load_path|
matcher = /\A#{Regexp.escape(load_path)}\/(.*)\.rb\Z/
Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
@@ -522,15 +538,9 @@ module Rails
end
initializer :append_assets_path do |app|
- if app.config.assets.respond_to?(:prepend_path)
- app.config.assets.prepend_path(*paths["vendor/assets"].existent)
- app.config.assets.prepend_path(*paths["lib/assets"].existent)
- app.config.assets.prepend_path(*paths["app/assets"].existent)
- else
- app.config.assets.paths.unshift(*paths["vendor/assets"].existent)
- app.config.assets.paths.unshift(*paths["lib/assets"].existent)
- app.config.assets.paths.unshift(*paths["app/assets"].existent)
- end
+ app.config.assets.paths.unshift(*paths["vendor/assets"].existent)
+ app.config.assets.paths.unshift(*paths["lib/assets"].existent)
+ app.config.assets.paths.unshift(*paths["app/assets"].existent)
end
initializer :prepend_helpers_path do |app|
@@ -567,12 +577,16 @@ module Rails
protected
+ def initialize_generators
+ require "rails/generators"
+ end
+
def routes?
defined?(@routes)
end
def has_migrations?
- paths["db/migrate"].first.present?
+ paths["db/migrate"].existent.any?
end
def find_root_with_flag(flag, default=nil)
diff --git a/railties/lib/rails/engine/commands.rb b/railties/lib/rails/engine/commands.rb
new file mode 100644
index 0000000000..3b0920e213
--- /dev/null
+++ b/railties/lib/rails/engine/commands.rb
@@ -0,0 +1,38 @@
+require 'active_support/core_ext/object/inclusion'
+
+ARGV << '--help' if ARGV.empty?
+
+aliases = {
+ "g" => "generate"
+}
+
+command = ARGV.shift
+command = aliases[command] || command
+
+require ENGINE_PATH
+engine = ::Rails::Engine.find(ENGINE_ROOT)
+
+case command
+when 'generate', 'destroy'
+ require 'rails/generators'
+ Rails::Generators.namespace = engine.railtie_namespace
+ engine.load_generators
+ require "rails/commands/#{command}"
+
+when '--version', '-v'
+ ARGV.unshift '--version'
+ require 'rails/commands/application'
+
+else
+ puts "Error: Command not recognized" unless command.in?(['-h', '--help'])
+ puts <<-EOT
+Usage: rails COMMAND [ARGS]
+
+The common rails commands available for engines are:
+ generate Generate new code (short-cut alias: "g")
+ destroy Undo code generated with "generate"
+
+All commands can be run with -h for more information.
+ EOT
+ exit(1)
+end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 09e505a75b..fdafc91fcb 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -20,6 +20,8 @@ module Rails
autoload :ResourceHelpers, 'rails/generators/resource_helpers'
autoload :TestCase, 'rails/generators/test_case'
+ mattr_accessor :namespace
+
DEFAULT_ALIASES = {
:rails => {
:actions => '-a',
@@ -51,7 +53,7 @@ module Rails
:helper => true,
:integration_tool => nil,
:javascripts => true,
- :javascript_engine => nil,
+ :javascript_engine => :js,
:orm => false,
:performance_tool => nil,
:resource_controller => :controller,
@@ -297,9 +299,6 @@ module Rails
return
rescue LoadError => e
raise unless e.message =~ /#{Regexp.escape(path)}$/
- rescue NameError => e
- 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}.\n#{e.backtrace.join("\n")}"
rescue Exception => e
warn "[WARNING] Could not load generator #{path.inspect}. Error: #{e.message}.\n#{e.backtrace.join("\n")}"
end
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index d31a3262e3..433a56dc57 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -114,11 +114,11 @@ module Rails
# git :add => "this.file that.rb"
# git :add => "onefile.rb", :rm => "badfile.cxx"
#
- def git(command={})
- if command.is_a?(Symbol)
- run "git #{command}"
+ def git(commands={})
+ if commands.is_a?(Symbol)
+ run "git #{commands}"
else
- command.each do |command, options|
+ commands.each do |command, options|
run "git #{command} #{options}"
end
end
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index caa9c1016c..bbdd000ad9 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -10,7 +10,7 @@ module Rails
module Generators
class AppBase < Base
DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
- JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 jdbcpostgresql )
+ JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc )
DATABASES.concat(JDBC_DATABASES)
attr_accessor :rails_template
@@ -37,6 +37,9 @@ module Rails
class_option :skip_active_record, :type => :boolean, :aliases => "-O", :default => false,
:desc => "Skip Active Record files"
+ class_option :skip_sprockets, :type => :boolean, :aliases => "-S", :default => false,
+ :desc => "Skip Sprockets files"
+
class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
:desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
@@ -64,8 +67,8 @@ module Rails
def initialize(*args)
@original_wd = Dir.pwd
-
super
+ convert_database_option_for_jruby
end
protected
@@ -124,11 +127,11 @@ module Rails
end
def include_all_railties?
- !options[:skip_active_record] && !options[:skip_test_unit]
+ !options[:skip_active_record] && !options[:skip_test_unit] && !options[:skip_sprockets]
end
def comment_if(value)
- options[value] ? '#' : ''
+ options[value] ? '# ' : ''
end
def rails_gemfile_entry
@@ -157,14 +160,26 @@ module Rails
when "postgresql" then "pg"
when "frontbase" then "ruby-frontbase"
when "mysql" then "mysql2"
- when "jdbcmysql" then "activerecord-jdbcmysql-adapter"
- when "jdbcsqlite3" then "activerecord-jdbcsqlite3-adapter"
- when "jdbcpostgresql" then "activerecord-jdbcpostgresql-adapter"
+ when "jdbcmysql" then "activerecord-jdbcmysql-adapter"
+ when "jdbcsqlite3" then "activerecord-jdbcsqlite3-adapter"
+ when "jdbcpostgresql" then "activerecord-jdbcpostgresql-adapter"
+ when "jdbc" then "activerecord-jdbc-adapter"
else options[:database]
end
end
- def gem_for_ruby_debugger
+ def convert_database_option_for_jruby
+ if defined?(JRUBY_VERSION)
+ case options[:database]
+ when "oracle" then options[:database].replace "jdbc"
+ when "postgresql" then options[:database].replace "jdbcpostgresql"
+ when "mysql" then options[:database].replace "jdbcmysql"
+ when "sqlite3" then options[:database].replace "jdbcsqlite3"
+ end
+ end
+ end
+
+ def ruby_debugger_gemfile_entry
if RUBY_VERSION < "1.9"
"gem 'ruby-debug'"
else
@@ -172,7 +187,7 @@ module Rails
end
end
- def gem_for_turn
+ def turn_gemfile_entry
unless RUBY_VERSION < "1.9.2" || options[:skip_test_unit]
<<-GEMFILE.strip_heredoc
group :test do
@@ -183,18 +198,34 @@ module Rails
end
end
- def gem_for_javascript
+ def assets_gemfile_entry
+ <<-GEMFILE.strip_heredoc
+ group :assets do
+ gem 'sass-rails', :git => 'git://github.com/rails/sass-rails'
+ gem 'coffee-rails', :git => 'git://github.com/rails/coffee-rails'
+ gem 'uglifier'
+ end
+ GEMFILE
+ end
+
+ def javascript_gemfile_entry
"gem '#{options[:javascript]}-rails'" unless options[:skip_javascript]
end
def bundle_command(command)
- require 'bundler'
- require 'bundler/cli'
-
say_status :run, "bundle #{command}"
- Bundler::CLI.new.send(command)
- rescue
- say_status :failure, "bundler raised an exception, are you offline?", :red
+
+ # We are going to shell out rather than invoking Bundler::CLI.new(command)
+ # because `rails new` loads the Thor gem and on the other hand bundler uses
+ # its own vendored Thor, which could be a different version. Running both
+ # things in the same process is a recipe for a night with paracetamol.
+ #
+ # We use backticks and #print here instead of vanilla #system because it
+ # is easier to silence stdout in the existing test suite this way. The
+ # end-user gets the bundler commands called anyway, so no big deal.
+ #
+ # Thanks to James Tucker for the Gem tricks involved in this call.
+ print `"#{Gem.ruby}" -rubygems "#{Gem.bin_path('bundler', 'bundle')}" #{command}`
end
def run_bundle
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index 1f6a7a2f59..b9dc31457a 100644
--- a/railties/lib/rails/generators/base.rb
+++ b/railties/lib/rails/generators/base.rb
@@ -259,9 +259,9 @@ module Rails
extra << false unless Object.method(:const_defined?).arity == 1
# Extract the last Module in the nesting
- last = nesting.inject(Object) do |last, nest|
- break unless last.const_defined?(nest, *extra)
- last.const_get(nest)
+ last = nesting.inject(Object) do |last_module, nest|
+ break unless last_module.const_defined?(nest, *extra)
+ last_module.const_get(nest)
end
if last && last.const_defined?(last_name.camelize, *extra)
diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb
index 9450894b05..f9f89c9f1d 100644
--- a/railties/lib/rails/generators/generated_attribute.rb
+++ b/railties/lib/rails/generators/generated_attribute.rb
@@ -7,7 +7,7 @@ module Rails
attr_accessor :name, :type
def initialize(name, type)
- raise Thor::Error, "Missing type for attribute '#{name}'.\nExample: '#{name}:string' where string is the type." if type.blank?
+ type = :string if type.blank?
@name, @type = name, type.to_sym
end
diff --git a/railties/lib/rails/generators/js/assets/assets_generator.rb b/railties/lib/rails/generators/js/assets/assets_generator.rb
new file mode 100644
index 0000000000..d134a9e392
--- /dev/null
+++ b/railties/lib/rails/generators/js/assets/assets_generator.rb
@@ -0,0 +1,13 @@
+require "rails/generators/named_base"
+
+module Js
+ module Generators
+ class AssetsGenerator < Rails::Generators::NamedBase
+ source_root File.expand_path("../templates", __FILE__)
+
+ def copy_javascript
+ copy_file "javascript.js", File.join('app/assets/javascripts', class_path, "#{file_name}.js")
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/js/assets/templates/javascript.js b/railties/lib/rails/generators/js/assets/templates/javascript.js
new file mode 100644
index 0000000000..dee720facd
--- /dev/null
+++ b/railties/lib/rails/generators/js/assets/templates/javascript.js
@@ -0,0 +1,2 @@
+// Place all the behaviors and hooks related to the matching controller here.
+// All this logic will automatically be available in application.js.
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 7e7f8d2d08..c6c0392f43 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -63,9 +63,7 @@ module Rails
end
def namespace
- @namespace ||= if defined?(Rails) && Rails.application
- Rails.application.class.parents.detect { |n| n.respond_to?(:_railtie) }
- end
+ Rails::Generators.namespace
end
def namespaced?
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 242677cc65..6af9d299aa 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -88,6 +88,7 @@ module Rails
def lib
empty_directory "lib"
empty_directory_with_gitkeep "lib/tasks"
+ empty_directory_with_gitkeep "lib/assets"
end
def log
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index ebe38bf8e6..88eea40b1b 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -5,13 +5,13 @@ source 'http://rubygems.org'
<%= database_gemfile_entry -%>
<%= "gem 'jruby-openssl'\n" if defined?(JRUBY_VERSION) -%>
-# Asset template engines
<%= "gem 'json'\n" if RUBY_VERSION < "1.9.2" -%>
-gem 'sass-rails'
-gem 'coffee-script'
-gem 'uglifier'
-<%= gem_for_javascript %>
+# Gems used only for assets and not required
+# in production environments by default.
+<%= assets_gemfile_entry %>
+
+<%= javascript_gemfile_entry %>
# Use unicorn as the web server
# gem 'unicorn'
@@ -20,6 +20,6 @@ gem 'uglifier'
# gem 'capistrano'
# To use debugger
-# <%= gem_for_ruby_debugger %>
+# <%= ruby_debugger_gemfile_entry %>
-<%= gem_for_turn -%>
+<%= turn_gemfile_entry -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
index 19294b3478..f33a7f4ac2 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
@@ -1,9 +1,15 @@
-// This is a manifest file that'll be compiled into including all the files listed below.
-// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
-// be included in the compiled file accessible from http://example.com/assets/application.js
+// This is a manifest file that'll be compiled into application.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
+//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
+// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
+// GO AFTER THE REQUIRES BELOW.
+//
<% unless options[:skip_javascript] -%>
//= require <%= options[:javascript] %>
//= require <%= options[:javascript] %>_ujs
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
index fc25b5723f..9e07c7d9a9 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
@@ -1,7 +1,13 @@
/*
- * This is a manifest file that'll automatically include all the stylesheets available in this directory
- * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
- * the top of the compiled file, but it's generally better to create a new file per style scope.
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
+ * listed below.
+ *
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
+ *
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
+ * compiled file, but it's generally better to create a new file per style scope.
+ *
*= require_self
*= require_tree .
*/ \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index a097c77391..eaa31e7386 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -4,16 +4,18 @@ require File.expand_path('../boot', __FILE__)
require 'rails/all'
<% else -%>
# Pick the frameworks you want:
-<%= comment_if :skip_active_record %> require "active_record/railtie"
+<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
+<%= comment_if :skip_sprockets %> require "sprockets/railtie"
<%= comment_if :skip_test_unit %> require "rails/test_unit/railtie"
<% end -%>
-# If you have a Gemfile, require the gems listed there, including any gems
-# you've limited to :test, :development, or :production.
-Bundler.require(:default, Rails.env) if defined?(Bundler)
+# If you have a Gemfile, require the default gems, the ones in the
+# current environment and also include :assets gems if in development
+# or test environments.
+Bundler.require *Rails.groups(:assets => %w(development test)) if defined?(Bundler)
module <%= app_const_base %>
class Application < Rails::Application
@@ -45,7 +47,9 @@ module <%= app_const_base %>
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
+ <% unless options.skip_sprockets? %>
# Enable the asset pipeline
config.assets.enabled = true
+ <% end %>
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
new file mode 100644
index 0000000000..1d2bf08b91
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
@@ -0,0 +1,62 @@
+# If you are using mssql, derby, hsqldb, or h2 with one of the
+# ActiveRecord JDBC adapters, install the appropriate driver, e.g.,:
+# gem install activerecord-jdbcmssql-adapter
+#
+# Configure using Gemfile:
+# gem 'activerecord-jdbcmssql-adapter'
+#
+#development:
+# adapter: mssql
+# username: <%= app_name %>
+# password:
+# host: localhost
+# database: <%= app_name %>_development
+#
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
+#
+#test:
+# adapter: mssql
+# username: <%= app_name %>
+# password:
+# host: localhost
+# database: <%= app_name %>_test
+#
+#production:
+# adapter: mssql
+# username: <%= app_name %>
+# password:
+# host: localhost
+# database: <%= app_name %>_production
+
+# If you are using oracle, db2, sybase, informix or prefer to use the plain
+# JDBC adapter, configure your database setting as the example below (requires
+# you to download and manually install the database vendor's JDBC driver .jar
+# file). See your driver documentation for the apropriate driver class and
+# connection string:
+
+development:
+ adapter: jdbc
+ username: <%= app_name %>
+ password:
+ driver:
+ url: jdbc:db://localhost/<%= app_name %>_development
+
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
+
+test:
+ adapter: jdbc
+ username: <%= app_name %>
+ password:
+ driver:
+ url: jdbc:db://localhost/<%= app_name %>_test
+
+production:
+ adapter: jdbc
+ username: <%= app_name %>
+ password:
+ driver:
+ url: jdbc:db://localhost/<%= app_name %>_production
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
index 6bf83e86a5..5a594ac1f3 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
@@ -9,7 +9,7 @@
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
- adapter: jdbcmysql
+ adapter: mysql
database: <%= app_name %>_development
username: root
password:
@@ -19,14 +19,14 @@ development:
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: jdbcmysql
+ adapter: mysql
database: <%= app_name %>_test
username: root
password:
host: localhost
production:
- adapter: jdbcmysql
+ adapter: mysql
database: <%= app_name %>_production
username: root
password:
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
index 0c7f45322b..fe9466b366 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
@@ -1,19 +1,10 @@
-# PostgreSQL. Versions 7.4 and 8.x are supported.
-#
-# Install the pg driver:
-# gem install pg
-# On Mac OS X with macports:
-# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
-# On Windows:
-# gem install pg
-# Choose the win32 build.
-# Install PostgreSQL and put its /bin directory on your path.
+# PostgreSQL. Versions 8.2 and up are supported.
#
# Configure Using Gemfile
# gem 'activerecord-jdbcpostgresql-adapter'
development:
- adapter: jdbcpostgresql
+ adapter: postgresql
encoding: unicode
database: <%= app_name %>_development
username: <%= app_name %>
@@ -38,14 +29,14 @@ development:
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: jdbcpostgresql
+ adapter: postgresql
encoding: unicode
database: <%= app_name %>_test
username: <%= app_name %>
password:
production:
- adapter: jdbcpostgresql
+ adapter: postgresql
encoding: unicode
database: <%= app_name %>_production
username: <%= app_name %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
index 6d241d57ae..175f3eb3db 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
@@ -5,16 +5,16 @@
# gem 'activerecord-jdbcsqlite3-adapter'
#
development:
- adapter: jdbcsqlite3
+ adapter: sqlite3
database: db/development.sqlite3
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: jdbcsqlite3
+ adapter: sqlite3
database: db/test.sqlite3
production:
- adapter: jdbcsqlite3
+ adapter: sqlite3
database: db/production.sqlite3
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
index 467dfc3956..f08f86aac3 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
@@ -1,4 +1,4 @@
-# PostgreSQL. Versions 7.4 and 8.x are supported.
+# PostgreSQL. Versions 8.2 and up are supported.
#
# Install the pg driver:
# gem install pg
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
index dcf4ace264..3e0c29a587 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
@@ -2,7 +2,7 @@
# Settings specified here will take precedence over those in config/application.rb
# In the development environment your application's code is reloaded on
- # every request. This slows down response time but is perfect for development
+ # every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
@@ -22,6 +22,11 @@
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
+ <%- unless options.skip_active_record? -%>
+ # Raise exception on mass assignment protection for ActiveRecord models
+ config.active_record.mass_assignment_sanitizer = :strict
+ <%- end -%>
+
# Do not compress assets
config.assets.compress = false
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index 60e26755fe..06ed890e05 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -14,9 +14,6 @@
# Compress JavaScripts and CSS
config.assets.compress = true
- # Specify the default JavaScript compressor
- config.assets.js_compressor = :uglifier
-
# Specifies the header that your server uses for sending files
# (comment out if your front-end server doesn't support this)
config.action_dispatch.x_sendfile_header = "X-Sendfile" # Use 'X-Accel-Redirect' for nginx
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
index 8d11377211..ee068b0202 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
@@ -2,9 +2,9 @@
# Settings specified here will take precedence over those in config/application.rb
# The test environment is used exclusively to run your application's
- # test suite. You never need to work with it otherwise. Remember that
+ # test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
- # and recreated between test runs. Don't rely on the data there!
+ # and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Configure static asset server for tests with Cache-Control for performance
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt
index e56195da80..fa1548db8b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt
@@ -1,7 +1,7 @@
# Be sure to restart your server when you modify this file.
#
-# This file contains the settings for ActionController::ParametersWrapper
-# which will be enabled by default in the upcoming version of Ruby on Rails.
+# This file contains settings for ActionController::ParamsWrapper which
+# is enabled by default.
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActionController::Base.wrap_parameters <%= key_value :format, "[:json]" %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
index d50f536164..ea81748464 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
@@ -54,5 +54,5 @@
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
- # match ':controller(/:action(/:id(.:format)))'
+ # match ':controller(/:action(/:id))(.:format)'
end
diff --git a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb b/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
index 5d1be041a5..3fea27b916 100644
--- a/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
+++ b/railties/lib/rails/generators/rails/app/templates/test/performance/browsing_test.rb
@@ -5,7 +5,7 @@ class BrowsingTest < ActionDispatch::PerformanceTest
# Refer to the documentation for all available options
# self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
# :output => 'tmp/performance', :formats => [:flat] }
-
+
def test_homepage
get '/'
end
diff --git a/railties/lib/rails/generators/rails/assets/USAGE b/railties/lib/rails/generators/rails/assets/USAGE
index c5375cdc06..d2e5ed4482 100644
--- a/railties/lib/rails/generators/rails/assets/USAGE
+++ b/railties/lib/rails/generators/rails/assets/USAGE
@@ -7,7 +7,7 @@ Description:
This generates a JavaScript stub in app/assets/javascripts and a stylesheet
stub in app/assets/stylesheets.
-
+
If CoffeeScript is available, JavaScripts will be generated with the .coffee extension.
If Sass 3 is available, stylesheets will be generated with the .scss extension.
diff --git a/railties/lib/rails/generators/rails/assets/assets_generator.rb b/railties/lib/rails/generators/rails/assets/assets_generator.rb
index db3422fe83..2e7f25a0b7 100644
--- a/railties/lib/rails/generators/rails/assets/assets_generator.rb
+++ b/railties/lib/rails/generators/rails/assets/assets_generator.rb
@@ -7,21 +7,14 @@ module Rails
class_option :javascript_engine, :desc => "Engine for JavaScripts"
class_option :stylesheet_engine, :desc => "Engine for Stylesheets"
- def create_javascript_files
- return unless options.javascripts?
- copy_file "javascript.#{javascript_extension}",
- File.join('app/assets/javascripts', class_path, "#{asset_name}.#{javascript_extension}")
- end
-
protected
def asset_name
file_name
end
- def javascript_extension
- options.javascript_engine.present? ?
- "js.#{options.javascript_engine}" : "js"
+ hook_for :javascript_engine do |javascript_engine|
+ invoke javascript_engine, [name] if options[:javascripts]
end
hook_for :stylesheet_engine do |stylesheet_engine|
diff --git a/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee b/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee
deleted file mode 100644
index 761567942f..0000000000
--- a/railties/lib/rails/generators/rails/assets/templates/javascript.js.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
index 4967d1793c..7c0a2b9cf4 100644
--- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
@@ -11,15 +11,15 @@ module Rails
def app
if mountable?
directory "app"
- template "#{app_templates_dir}/app/views/layouts/application.html.erb.tt",
+ template "app/views/layouts/application.html.erb.tt",
"app/views/layouts/#{name}/application.html.erb"
- empty_directory_with_gitkeep "app/assets/images"
+ empty_directory_with_gitkeep "app/assets/images/#{name}"
elsif full?
empty_directory_with_gitkeep "app/models"
empty_directory_with_gitkeep "app/controllers"
empty_directory_with_gitkeep "app/views"
empty_directory_with_gitkeep "app/helpers"
- empty_directory_with_gitkeep "app/assets/images"
+ empty_directory_with_gitkeep "app/assets/images/#{name}"
end
end
@@ -108,9 +108,9 @@ task :default => :test
def stylesheets
if mountable?
copy_file "#{app_templates_dir}/app/assets/stylesheets/application.css",
- "app/assets/stylesheets/application.css"
+ "app/assets/stylesheets/#{name}/application.css"
elsif full?
- empty_directory_with_gitkeep "app/assets/stylesheets"
+ empty_directory_with_gitkeep "app/assets/stylesheets/#{name}"
end
end
@@ -118,14 +118,16 @@ task :default => :test
return if options.skip_javascript?
if mountable?
- copy_file "#{app_templates_dir}/app/assets/javascripts/application.js.tt",
- "app/assets/javascripts/application.js"
+ template "#{app_templates_dir}/app/assets/javascripts/application.js.tt",
+ "app/assets/javascripts/#{name}/application.js"
elsif full?
- empty_directory_with_gitkeep "app/assets/javascripts"
+ empty_directory_with_gitkeep "app/assets/javascripts/#{name}"
end
end
def script(force = false)
+ return unless full?
+
directory "script", :force => force do |content|
"#{shebang}\n" + content
end
@@ -258,7 +260,7 @@ task :default => :test
elsif RESERVED_NAMES.include?(name)
raise Error, "Invalid plugin name #{name}. Please give a name which does not match one of the reserved rails words."
elsif Object.const_defined?(camelized)
- raise Error, "Invalid plugin name #{name}, constant #{camelized} is already in use. Please choose another application name."
+ raise Error, "Invalid plugin name #{name}, constant #{camelized} is already in use. Please choose another plugin name."
end
end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec
index 15299ddb9f..56b06829d8 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec
@@ -5,5 +5,8 @@ Gem::Specification.new do |s|
s.summary = "Insert <%= camelized %> summary."
s.description = "Insert <%= camelized %> description."
s.files = Dir["{app,config,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
+<% unless options.skip_test_unit? -%>
+ s.test_files = Dir["test/**/*"]
+<% end -%>
s.version = "0.0.1"
end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
index 29900c93dc..7e6eb18341 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
@@ -6,6 +6,9 @@ source "http://rubygems.org"
<%= database_gemfile_entry -%>
<% end -%>
-if RUBY_VERSION < '1.9'
- gem "ruby-debug", ">= 0.10.3"
-end
+<% if mountable? -%>
+<%= javascript_gemfile_entry -%>
+<% end -%>
+
+# To use debugger
+# <%= ruby_debugger_gemfile_entry %> \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
index 1bf9c8c831..b28a842731 100755
--- a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
@@ -4,8 +4,13 @@ begin
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
-
-require 'rdoc/task'
+begin
+ require 'rdoc/task'
+rescue LoadError
+ require 'rdoc/rdoc'
+ require 'rake/rdoctask'
+ RDoc::Task = Rake::RDocTask
+end
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt
new file mode 100644
index 0000000000..01550dec2f
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/app/views/layouts/application.html.erb.tt
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title><%= camelized %></title>
+ <%%= stylesheet_link_tag "<%= name %>/application" %>
+ <%%= javascript_include_tag "<%= name %>/application" %>
+ <%%= csrf_meta_tags %>
+</head>
+<body>
+
+<%%= yield %>
+
+</body>
+</html>
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb
index aa8ea77bae..967668fe66 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb
@@ -1,5 +1,5 @@
module <%= camelized %>
- class Engine < Rails::Engine
+ class Engine < ::Rails::Engine
<% if mountable? -%>
isolate_namespace <%= camelized %>
<% end -%>
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
index 8b68280a5e..4864ead960 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
@@ -1,13 +1,15 @@
require File.expand_path('../boot', __FILE__)
-<% unless options[:skip_active_record] -%>
+<% if include_all_railties? -%>
require 'rails/all'
<% else -%>
-# require "active_record/railtie"
+# Pick the frameworks you want:
+<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
-require "rails/test_unit/railtie"
+<%= comment_if :skip_sprockets %> require "sprockets/railtie"
+<%= comment_if :skip_test_unit %> require "rails/test_unit/railtie"
<% end -%>
Bundler.require
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt
index ebd5a77dd5..aa87d1b50c 100644
--- a/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt
@@ -1,5 +1,7 @@
-#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
-ENGINE_PATH = File.expand_path('../..', __FILE__)
-load File.expand_path('../../<%= dummy_path %>/script/rails', __FILE__)
+ENGINE_ROOT = File.expand_path('../..', __FILE__)
+ENGINE_PATH = File.expand_path('../../lib/<%= name -%>/engine', __FILE__)
+
+require 'rails/all'
+require 'rails/engine/commands'
diff --git a/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb b/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb
index e7a06e4a73..dea7e22196 100644
--- a/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb
+++ b/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb
@@ -1,8 +1,6 @@
require 'test_helper'
class <%= class_name %>Test < ActionDispatch::IntegrationTest
- fixtures :all
-
# test "the truth" do
# assert true
# end
diff --git a/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb b/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb
index 14a878328b..d296b26b16 100644
--- a/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb
+++ b/railties/lib/rails/generators/test_unit/performance/templates/performance_test.rb
@@ -5,7 +5,7 @@ class <%= class_name %>Test < ActionDispatch::PerformanceTest
# Refer to the documentation for all available options
# self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory]
# :output => 'tmp/performance', :formats => [:flat] }
-
+
def test_homepage
get '/'
end
diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb
index d05e031f56..a1e15092b2 100644
--- a/railties/lib/rails/info.rb
+++ b/railties/lib/rails/info.rb
@@ -78,6 +78,10 @@ module Rails
Rails::VERSION::STRING
end
+ property 'JavaScript Runtime' do
+ ExecJS.runtime.name
+ end
+
# Versions of each Rails framework (Active Record, Action Pack,
# Active Resource, Action Mailer, and Active Support).
frameworks.each do |framework|
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index 65c567d72f..8c88b25617 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -1,6 +1,7 @@
require 'rails/initializable'
require 'rails/configuration'
require 'active_support/inflector'
+require 'active_support/core_ext/module/introspection'
module Rails
# Railtie is the core of the Rails framework and provides several hooks to extend
@@ -83,7 +84,7 @@ module Rails
# == Loading rake tasks and generators
#
# If your railtie has rake tasks, you can tell Rails to load them through the method
- # rake tasks:
+ # rake_tasks:
#
# class MyRailtie < Rails::Railtie
# rake_tasks do
@@ -173,11 +174,11 @@ module Rails
def eager_load!
end
- def load_console(app)
+ def load_console(app=self)
self.class.console.each { |block| block.call(app) }
end
- def load_tasks(app)
+ def load_tasks(app=self)
extend Rake::DSL if defined? Rake::DSL
self.class.rake_tasks.each { |block| block.call(app) }
@@ -189,8 +190,12 @@ module Rails
end
end
- def load_generators(app)
+ def load_generators(app=self)
self.class.generators.each { |block| block.call(app) }
end
+
+ def railtie_namespace
+ @railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:_railtie) }
+ end
end
end
diff --git a/railties/lib/rails/railtie/configurable.rb b/railties/lib/rails/railtie/configurable.rb
index 920ab67ff1..53796c74cf 100644
--- a/railties/lib/rails/railtie/configurable.rb
+++ b/railties/lib/rails/railtie/configurable.rb
@@ -1,3 +1,5 @@
+require 'active_support/concern'
+
module Rails
class Railtie
module Configurable
diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb
index 6d6e7f8b59..1eed763aa3 100644
--- a/railties/lib/rails/source_annotation_extractor.rb
+++ b/railties/lib/rails/source_annotation_extractor.rb
@@ -28,9 +28,9 @@ class SourceAnnotationExtractor
end
end
- # Prints all annotations with tag +tag+ under the root directories +app+, +lib+,
- # and +test+ (recursively). Only filenames with extension +.builder+, +.rb+,
- # +.rxml+, +.rhtml+, or +.erb+ are taken into account. The +options+
+ # Prints all annotations with tag +tag+ under the root directories +app+, +config+, +lib+,
+ # +script+, and +test+ (recursively). Only filenames with extension
+ # +.builder+, +.rb+, +.rxml+, +.rhtml+, or +.erb+ are taken into account. The +options+
# hash is passed to each annotation's +to_s+.
#
# This class method is the single entry point for the rake tasks.
@@ -49,7 +49,7 @@ class SourceAnnotationExtractor
# with their annotations. Only files with annotations are included, and only
# those with extension +.builder+, +.rb+, +.rxml+, +.rhtml+, and +.erb+
# are taken into account.
- def find(dirs=%w(app lib test))
+ def find(dirs=%w(app config lib script test))
dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
end
diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb
index 166d518f7c..9807000578 100644
--- a/railties/lib/rails/tasks.rb
+++ b/railties/lib/rails/tasks.rb
@@ -3,7 +3,6 @@ $VERBOSE = nil
# Load Rails rakefile extensions
%w(
annotations
- assets
documentation
framework
log
diff --git a/railties/lib/rails/tasks/assets.rake b/railties/lib/rails/tasks/assets.rake
deleted file mode 100644
index 158df31749..0000000000
--- a/railties/lib/rails/tasks/assets.rake
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace :assets do
- desc "Compile all the assets named in config.assets.precompile"
- task :precompile => :environment do
- # Give assets access to asset_path
- ActionView::Helpers::SprocketsHelper
-
- assets = Rails.application.config.assets.precompile
- Rails.application.assets.precompile(*assets)
- end
-end
diff --git a/railties/lib/rails/tasks/documentation.rake b/railties/lib/rails/tasks/documentation.rake
index c8b4040151..79255d1f56 100644
--- a/railties/lib/rails/tasks/documentation.rake
+++ b/railties/lib/rails/tasks/documentation.rake
@@ -1,4 +1,10 @@
-require 'rdoc/task'
+begin
+ require 'rdoc/task'
+rescue LoadError
+ require 'rdoc/rdoc'
+ require 'rake/rdoctask'
+ RDoc::Task = Rake::RDocTask
+end
# Monkey-patch to remove redoc'ing and clobber descriptions to cut down on rake -T noise
class RDocTaskWithoutDescriptions < RDoc::Task
diff --git a/railties/lib/rails/tasks/engine.rake b/railties/lib/rails/tasks/engine.rake
index 2f0e7be896..2152e811f5 100644
--- a/railties/lib/rails/tasks/engine.rake
+++ b/railties/lib/rails/tasks/engine.rake
@@ -67,3 +67,5 @@ def find_engine_path(path)
find_engine_path(File.expand_path('..', path))
end
end
+
+Rake.application.invoke_task(:load_app)
diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake
index 28dc40379b..b9877a83b5 100644
--- a/railties/lib/rails/test_unit/testing.rake
+++ b/railties/lib/rails/test_unit/testing.rake
@@ -79,10 +79,14 @@ task :test do
Rake::Task[task].invoke
nil
rescue => e
- task
+ { :task => task, :exception => e }
end
end.compact
- abort "Errors running #{errors * ', '}!" if errors.any?
+
+ if errors.any?
+ puts errors.map { |e| "Errors running #{e[:task]}! #{e[:exception].inspect}" }.join("\n")
+ abort
+ end
end
namespace :test do
diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb
index 3d6ecb9d30..254227ecf7 100644
--- a/railties/lib/rails/version.rb
+++ b/railties/lib/rails/version.rb
@@ -1,9 +1,9 @@
module Rails
module VERSION #:nodoc:
MAJOR = 3
- MINOR = 1
+ MINOR = 2
TINY = 0
- PRE = "rc1"
+ PRE = "beta"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
diff --git a/railties/railties.gemspec b/railties/railties.gemspec
index f1c92bd5d4..b917128885 100644
--- a/railties/railties.gemspec
+++ b/railties/railties.gemspec
@@ -15,11 +15,15 @@ Gem::Specification.new do |s|
s.files = Dir['CHANGELOG', 'README.rdoc', 'bin/**/*', 'guides/**/*', 'lib/**/{*,.[a-z]*}']
s.require_path = 'lib'
+ s.bindir = 'bin'
+ s.executables = ['rails']
+
s.rdoc_options << '--exclude' << '.'
s.add_dependency('rake', '>= 0.8.7')
s.add_dependency('thor', '~> 0.14.6')
s.add_dependency('rack-ssl', '~> 1.3.2')
+ s.add_dependency('rdoc', '~> 3.4')
s.add_dependency('activesupport', version)
s.add_dependency('actionpack', version)
end
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb
index 8b38081667..1c3f8a701a 100644
--- a/railties/test/abstract_unit.rb
+++ b/railties/test/abstract_unit.rb
@@ -10,7 +10,6 @@ require 'active_support/core_ext/logger'
require 'action_controller'
require 'rails/all'
-# TODO: Remove these hacks
module TestApp
class Application < Rails::Application
config.root = File.dirname(__FILE__)
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index 98a702f134..e1eee71a9e 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -1,8 +1,9 @@
require 'isolation/abstract_unit'
+require 'active_support/core_ext/kernel/reporting'
require 'rack/test'
module ApplicationTests
- class RoutingTest < Test::Unit::TestCase
+ class AssetsTest < Test::Unit::TestCase
include ActiveSupport::Testing::Isolation
include Rack::Test::Methods
@@ -11,6 +12,10 @@ module ApplicationTests
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
def app
@app ||= Rails.application
end
@@ -30,6 +35,45 @@ module ApplicationTests
assert_match "alert()", last_response.body
end
+ test "assets do not require compressors until it is used" do
+ app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
+ ENV["RAILS_ENV"] = "production"
+ require "#{app_path}/config/environment"
+
+ assert !defined?(Uglifier)
+ get "/assets/demo.js"
+ assert_match "alert()", last_response.body
+ assert defined?(Uglifier)
+ end
+
+ test "assets are compiled properly" do
+ app_file "app/assets/javascripts/application.js", "alert();"
+ app_file "app/assets/javascripts/foo/application.js", "alert();"
+
+ capture(:stdout) do
+ Dir.chdir(app_path){ `bundle exec rake assets:precompile` }
+ end
+ files = Dir["#{app_path}/public/assets/application-*.js"]
+ files << Dir["#{app_path}/public/assets/foo/application-*.js"].first
+ files.each do |file|
+ assert_not_nil file, "Expected application.js asset to be generated, but none found"
+ assert_equal "alert();\n", File.read(file)
+ end
+ end
+
+ test "assets are cleaned up properly" do
+ app_file "public/assets/application.js", "alert();"
+ app_file "public/assets/application.css", "a { color: green; }"
+ app_file "public/assets/subdir/broken.png", "not really an image file"
+
+ capture(:stdout) do
+ Dir.chdir(app_path){ `bundle exec rake assets:clean` }
+ end
+
+ files = Dir["#{app_path}/public/assets/**/*"]
+ assert_equal 0, files.length, "Expected no assets, but found #{files.join(', ')}"
+ end
+
test "does not stream session cookies back" do
app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 0e27c9606d..448982f9de 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -35,9 +35,25 @@ module ApplicationTests
end
def teardown
+ teardown_app
FileUtils.rm_rf(new_app) if File.directory?(new_app)
end
+ test "Rails.groups returns available groups" do
+ require "rails"
+
+ Rails.env = "development"
+ assert_equal [:default, "development"], Rails.groups
+ assert_equal [:default, "development", :assets], Rails.groups(:assets => [:development])
+ assert_equal [:default, "development", :another, :assets], Rails.groups(:another, :assets => %w(development))
+
+ Rails.env = "test"
+ assert_equal [:default, "test"], Rails.groups(:assets => [:development])
+
+ ENV["RAILS_GROUPS"] = "javascripts,stylesheets"
+ assert_equal [:default, "test", "javascripts", "stylesheets"], Rails.groups
+ end
+
test "Rails.application is nil until app is initialized" do
require 'rails'
assert_nil Rails.application
@@ -500,5 +516,14 @@ module ApplicationTests
get "/", { :format => :xml }, "HTTP_ACCEPT" => "application/xml"
assert_equal 'XML', last_response.body
end
+
+ test "Rails.application#env_config exists and include some existing parameters" do
+ make_basic_app
+
+ assert_respond_to app, :env_config
+ assert_equal app.env_config['action_dispatch.parameter_filter'], app.config.filter_parameters
+ assert_equal app.env_config['action_dispatch.secret_token'], app.config.secret_token
+ assert_equal app.env_config['action_dispatch.show_exceptions'], app.config.action_dispatch.show_exceptions
+ end
end
end
diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb
index db8f1f2ac6..1528d5dd87 100644
--- a/railties/test/application/console_test.rb
+++ b/railties/test/application/console_test.rb
@@ -1,13 +1,17 @@
require 'isolation/abstract_unit'
class ConsoleTest < Test::Unit::TestCase
- include ActiveSupport::Testing::Isolation
+ include ActiveSupport::Testing::Isolation
def setup
build_app
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
def load_environment(sandbox = false)
require "#{rails_root}/config/environment"
Rails.application.sandbox = sandbox
diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb
index 1ca9515335..4365d00b1f 100644
--- a/railties/test/application/generators_test.rb
+++ b/railties/test/application/generators_test.rb
@@ -9,6 +9,10 @@ module ApplicationTests
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
def app_const
@app_const ||= Class.new(Rails::Application)
end
diff --git a/railties/test/application/initializers/boot_test.rb b/railties/test/application/initializers/boot_test.rb
index 5ec562f12f..b1e01dc13f 100644
--- a/railties/test/application/initializers/boot_test.rb
+++ b/railties/test/application/initializers/boot_test.rb
@@ -9,8 +9,12 @@ module ApplicationTests
# boot_rails
end
+ def teardown
+ # teardown_app
+ end
+
test "booting rails sets the load paths correctly" do
# This test is pending reworking the boot process
end
end
-end \ No newline at end of file
+end
diff --git a/railties/test/application/initializers/check_ruby_version_test.rb b/railties/test/application/initializers/check_ruby_version_test.rb
index 5b6196307d..df7e9696a9 100644
--- a/railties/test/application/initializers/check_ruby_version_test.rb
+++ b/railties/test/application/initializers/check_ruby_version_test.rb
@@ -9,6 +9,10 @@ module ApplicationTests
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
test "rails initializes with ruby 1.8.7 or later, except for 1.9.1" do
if RUBY_VERSION < '1.8.7'
assert_rails_does_not_boot
diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb
index 196d121c14..446c85d65a 100644
--- a/railties/test/application/initializers/frameworks_test.rb
+++ b/railties/test/application/initializers/frameworks_test.rb
@@ -10,6 +10,10 @@ module ApplicationTests
FileUtils.rm_rf "#{app_path}/config/environments"
end
+ def teardown
+ teardown_app
+ end
+
# AC & AM
test "set load paths set only if action controller or action mailer are in use" do
assert_nothing_raised NameError do
diff --git a/railties/test/application/initializers/hooks_test.rb b/railties/test/application/initializers/hooks_test.rb
index 198abbe861..8c7726339c 100644
--- a/railties/test/application/initializers/hooks_test.rb
+++ b/railties/test/application/initializers/hooks_test.rb
@@ -10,6 +10,10 @@ module ApplicationTests
FileUtils.rm_rf "#{app_path}/config/environments"
end
+ def teardown
+ teardown_app
+ end
+
test "load initializers" do
app_file "config/initializers/foo.rb", "$foo = true"
require "#{app_path}/config/environment"
diff --git a/railties/test/application/initializers/i18n_test.rb b/railties/test/application/initializers/i18n_test.rb
index 390f65ab5c..8c2c079fb8 100644
--- a/railties/test/application/initializers/i18n_test.rb
+++ b/railties/test/application/initializers/i18n_test.rb
@@ -11,6 +11,10 @@ module ApplicationTests
require "rails/all"
end
+ def teardown
+ teardown_app
+ end
+
def load_app
require "#{app_path}/config/environment"
end
@@ -48,7 +52,7 @@ module ApplicationTests
end
test "locale files should be added to the load path" do
- app_file "config/another_locale.yml", ""
+ app_file "config/another_locale.yml", "en:\nfoo: ~"
add_to_config <<-RUBY
config.i18n.load_path << config.root.join("config/another_locale.yml").to_s
@@ -127,7 +131,7 @@ en:
# Fallbacks
test "not using config.i18n.fallbacks does not initialize I18n.fallbacks" do
- I18n.backend = Class.new { include I18n::Backend::Base }.new
+ I18n.backend = Class.new(I18n::Backend::Simple).new
load_app
assert_no_fallbacks
end
@@ -141,7 +145,7 @@ en:
test "config.i18n.fallbacks = true initializes I18n.fallbacks with default settings even when backend changes" do
I18n::Railtie.config.i18n.fallbacks = true
- I18n::Railtie.config.i18n.backend = Class.new { include I18n::Backend::Base }.new
+ I18n::Railtie.config.i18n.backend = Class.new(I18n::Backend::Simple).new
load_app
assert I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
assert_fallbacks :de => [:de, :en]
diff --git a/railties/test/application/initializers/load_path_test.rb b/railties/test/application/initializers/load_path_test.rb
index 714d62311d..644b8208a9 100644
--- a/railties/test/application/initializers/load_path_test.rb
+++ b/railties/test/application/initializers/load_path_test.rb
@@ -10,6 +10,10 @@ module ApplicationTests
FileUtils.rm_rf "#{app_path}/config/environments"
end
+ def teardown
+ teardown_app
+ end
+
test "initializing an application adds the application paths to the load path" do
add_to_config <<-RUBY
config.root = "#{app_path}"
diff --git a/railties/test/application/initializers/notifications_test.rb b/railties/test/application/initializers/notifications_test.rb
index c87433db0d..b72c14eaf0 100644
--- a/railties/test/application/initializers/notifications_test.rb
+++ b/railties/test/application/initializers/notifications_test.rb
@@ -9,6 +9,10 @@ module ApplicationTests
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
def instrument(*args, &block)
ActiveSupport::Notifications.instrument(*args, &block)
end
diff --git a/railties/test/application/loading_test.rb b/railties/test/application/loading_test.rb
index c340465e87..47c6fd5c6e 100644
--- a/railties/test/application/loading_test.rb
+++ b/railties/test/application/loading_test.rb
@@ -8,6 +8,10 @@ class LoadingTest < Test::Unit::TestCase
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
def app
@app ||= Rails.application
end
diff --git a/railties/test/application/middleware/best_practices_test.rb b/railties/test/application/middleware/best_practices_test.rb
index 5b722e7510..1c88b9bf06 100644
--- a/railties/test/application/middleware/best_practices_test.rb
+++ b/railties/test/application/middleware/best_practices_test.rb
@@ -12,6 +12,10 @@ module ApplicationTests
simple_controller
end
+ def teardown
+ teardown_app
+ end
+
test "simple controller in production mode returns best standards" do
get '/foo'
assert_equal "IE=Edge,chrome=1", last_response.headers["X-UA-Compatible"]
diff --git a/railties/test/application/middleware/cache_test.rb b/railties/test/application/middleware/cache_test.rb
index a8033d2b23..e656ada3c0 100644
--- a/railties/test/application/middleware/cache_test.rb
+++ b/railties/test/application/middleware/cache_test.rb
@@ -11,6 +11,10 @@ module ApplicationTests
extend Rack::Test::Methods
end
+ def teardown
+ teardown_app
+ end
+
def simple_controller
controller :expires, <<-RUBY
class ExpiresController < ApplicationController
diff --git a/railties/test/application/middleware/remote_ip_test.rb b/railties/test/application/middleware/remote_ip_test.rb
index f28302d70a..da291f061c 100644
--- a/railties/test/application/middleware/remote_ip_test.rb
+++ b/railties/test/application/middleware/remote_ip_test.rb
@@ -10,6 +10,10 @@ module ApplicationTests
FileUtils.rm_rf "#{app_path}/config/environments"
end
+ def teardown
+ teardown_app
+ end
+
def app
@app ||= Rails.application
end
diff --git a/railties/test/application/middleware/sendfile_test.rb b/railties/test/application/middleware/sendfile_test.rb
index 0128261cd4..c7a1c573f9 100644
--- a/railties/test/application/middleware/sendfile_test.rb
+++ b/railties/test/application/middleware/sendfile_test.rb
@@ -10,6 +10,10 @@ module ApplicationTests
FileUtils.rm_rf "#{app_path}/config/environments"
end
+ def teardown
+ teardown_app
+ end
+
def app
@app ||= Rails.application
end
diff --git a/railties/test/application/middleware/show_exceptions_test.rb b/railties/test/application/middleware/show_exceptions_test.rb
index 5487e41e0a..e3f27f63c3 100644
--- a/railties/test/application/middleware/show_exceptions_test.rb
+++ b/railties/test/application/middleware/show_exceptions_test.rb
@@ -10,6 +10,10 @@ module ApplicationTests
FileUtils.rm_rf "#{app_path}/config/environments"
end
+ def teardown
+ teardown_app
+ end
+
def app
@app ||= Rails.application
end
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index 715798ca08..6a0a272073 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -11,6 +11,10 @@ module ApplicationTests
FileUtils.rm_rf "#{app_path}/config/environments"
end
+ def teardown
+ teardown_app
+ end
+
def app
@app ||= Rails.application
end
@@ -200,4 +204,4 @@ module ApplicationTests
AppTemplate::Application.middleware.map(&:klass).map(&:name)
end
end
-end \ No newline at end of file
+end
diff --git a/railties/test/application/paths_test.rb b/railties/test/application/paths_test.rb
index 03e0247556..0d22d8c19a 100644
--- a/railties/test/application/paths_test.rb
+++ b/railties/test/application/paths_test.rb
@@ -20,6 +20,10 @@ module ApplicationTests
@paths = Rails.application.config.paths
end
+ def teardown
+ teardown_app
+ end
+
def root(*path)
app_path(*path).to_s
end
diff --git a/railties/test/application/rack/logger_test.rb b/railties/test/application/rack/logger_test.rb
index 715af5c642..8b2b2f1802 100644
--- a/railties/test/application/rack/logger_test.rb
+++ b/railties/test/application/rack/logger_test.rb
@@ -14,6 +14,10 @@ module ApplicationTests
super
end
+ def teardown
+ teardown_app
+ end
+
def logs
@logs ||= @logger.logged(:info)
end
diff --git a/railties/test/application/rackup_test.rb b/railties/test/application/rackup_test.rb
index b0a9925890..ff9cdcadc7 100644
--- a/railties/test/application/rackup_test.rb
+++ b/railties/test/application/rackup_test.rb
@@ -15,6 +15,10 @@ module ApplicationTests
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
test "rails app is present" do
assert File.exist?(app_path("config"))
end
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index ab36ace5e5..7671c129e9 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -10,6 +10,10 @@ module ApplicationTests
FileUtils.rm_rf("#{app_path}/config/environments")
end
+ def teardown
+ teardown_app
+ end
+
def test_gems_tasks_are_loaded_first_than_application_ones
app_file "lib/tasks/app.rake", <<-RUBY
$task_loaded = Rake::Task.task_defined?("db:create:all")
@@ -55,6 +59,32 @@ module ApplicationTests
Dir.chdir(app_path){ `rake stats` }
end
+ def test_rake_test_error_output
+ Dir.chdir(app_path){ `rake db:migrate` }
+
+ app_file "config/database.yml", <<-RUBY
+ development:
+ RUBY
+
+ app_file "test/unit/one_unit_test.rb", <<-RUBY
+ RUBY
+
+ app_file "test/functional/one_functional_test.rb", <<-RUBY
+ raise RuntimeError
+ RUBY
+
+ app_file "test/integration/one_integration_test.rb", <<-RUBY
+ raise RuntimeError
+ RUBY
+
+ silence_stderr do
+ output = Dir.chdir(app_path){ `rake test` }
+ assert_match /Errors running test:units! #<ActiveRecord::AdapterNotSpecified/, output
+ assert_match /Errors running test:functionals! #<RuntimeError/, output
+ assert_match /Errors running test:integration! #<RuntimeError/, output
+ end
+ end
+
def test_rake_routes_output_strips_anchors_from_http_verbs
app_file "config/routes.rb", <<-RUBY
AppTemplate::Application.routes.draw do
@@ -113,7 +143,7 @@ module ApplicationTests
end
require "#{rails_root}/config/environment"
-
+
# loading a specific fixture
errormsg = Dir.chdir(app_path) { `rake db:fixtures:load FIXTURES=products` }
assert $?.success?, errormsg
@@ -121,5 +151,14 @@ module ApplicationTests
assert_equal 2, ::AppTemplate::Application::Product.count
assert_equal 0, ::AppTemplate::Application::User.count
end
+
+ def test_scaffold_tests_pass_by_default
+ content = Dir.chdir(app_path) do
+ `rails generate scaffold user username:string password:string`
+ `bundle exec rake db:migrate db:test:clone test`
+ end
+
+ assert_match(/7 tests, 10 assertions, 0 failures, 0 errors/, content)
+ end
end
-end
+end \ No newline at end of file
diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb
index e3a7f8a63c..3adf0ccd3e 100644
--- a/railties/test/application/routing_test.rb
+++ b/railties/test/application/routing_test.rb
@@ -11,6 +11,10 @@ module ApplicationTests
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
test "rails/info/properties in development" do
app("development")
get "/rails/info/properties"
diff --git a/railties/test/application/runner_test.rb b/railties/test/application/runner_test.rb
index 292d1e247f..4468fa295e 100644
--- a/railties/test/application/runner_test.rb
+++ b/railties/test/application/runner_test.rb
@@ -18,6 +18,14 @@ module ApplicationTests
MODEL
end
+ def teardown
+ teardown_app
+ end
+
+ def test_should_include_runner_in_shebang_line_in_help_without_option
+ assert_match "/rails runner", Dir.chdir(app_path) { `bundle exec rails runner` }
+ end
+
def test_should_include_runner_in_shebang_line_in_help
assert_match "/rails runner", Dir.chdir(app_path) { `bundle exec rails runner --help` }
end
diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb
index f96319f472..27a7959e84 100644
--- a/railties/test/application/test_test.rb
+++ b/railties/test/application/test_test.rb
@@ -9,6 +9,10 @@ module ApplicationTests
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
test "truth" do
app_file 'test/unit/foo_test.rb', <<-RUBY
require 'test_helper'
diff --git a/railties/test/fixtures/lib/generators/wrong_generator.rb b/railties/test/fixtures/lib/generators/wrong_generator.rb
deleted file mode 100644
index 6aa7cb052e..0000000000
--- a/railties/test/fixtures/lib/generators/wrong_generator.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# Old generator version
-class WrongGenerator < Rails::Generator::NamedBase
-end
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index c31c65a27d..81f0bf5e82 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -10,6 +10,7 @@ DEFAULT_APP_FILES = %w(
config.ru
app/assets/javascripts
app/assets/stylesheets
+ app/assets/images
app/controllers
app/helpers
app/mailers
@@ -22,8 +23,8 @@ DEFAULT_APP_FILES = %w(
doc
lib
lib/tasks
+ lib/assets
log
- app/assets/images
script/rails
test/fixtures
test/functional
@@ -47,11 +48,12 @@ class AppGeneratorTest < Rails::Generators::TestCase
::DEFAULT_APP_FILES
end
- def test_application_controller_and_layout_files
+ def test_assets
run_generator
assert_file "app/views/layouts/application.html.erb", /stylesheet_link_tag\s+"application"/
assert_file "app/views/layouts/application.html.erb", /javascript_include_tag\s+"application"/
assert_file "app/assets/stylesheets/application.css"
+ assert_file "config/application.rb", /config\.assets\.enabled = true/
end
def test_invalid_application_name_raises_an_error
@@ -123,18 +125,26 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_config_database_is_added_by_default
run_generator
assert_file "config/database.yml", /sqlite3/
- assert_file "Gemfile", /^gem\s+["']sqlite3["']$/
+ unless defined?(JRUBY_VERSION)
+ assert_file "Gemfile", /^gem\s+["']sqlite3["']$/
+ else
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/
+ end
end
def test_config_another_database
run_generator([destination_root, "-d", "mysql"])
assert_file "config/database.yml", /mysql/
- assert_file "Gemfile", /^gem\s+["']mysql2["']$/
+ unless defined?(JRUBY_VERSION)
+ assert_file "Gemfile", /^gem\s+["']mysql2["']$/
+ else
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbcmysql-adapter["']$/
+ end
end
def test_config_jdbcmysql_database
run_generator([destination_root, "-d", "jdbcmysql"])
- assert_file "config/database.yml", /jdbcmysql/
+ assert_file "config/database.yml", /mysql/
assert_file "Gemfile", /^gem\s+["']activerecord-jdbcmysql-adapter["']$/
# TODO: When the JRuby guys merge jruby-openssl in
# jruby this will be removed
@@ -143,28 +153,48 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_config_jdbcsqlite3_database
run_generator([destination_root, "-d", "jdbcsqlite3"])
- assert_file "config/database.yml", /jdbcsqlite3/
+ assert_file "config/database.yml", /sqlite3/
assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/
end
def test_config_jdbcpostgresql_database
run_generator([destination_root, "-d", "jdbcpostgresql"])
- assert_file "config/database.yml", /jdbcpostgresql/
+ assert_file "config/database.yml", /postgresql/
assert_file "Gemfile", /^gem\s+["']activerecord-jdbcpostgresql-adapter["']$/
end
+ def test_config_jdbc_database
+ run_generator([destination_root, "-d", "jdbc"])
+ assert_file "config/database.yml", /jdbc/
+ assert_file "config/database.yml", /mssql/
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbc-adapter["']$/
+ end
+
+ def test_config_jdbc_database_when_no_option_given
+ if defined?(JRUBY_VERSION)
+ run_generator([destination_root])
+ assert_file "config/database.yml", /sqlite3/
+ assert_file "Gemfile", /^gem\s+["']activerecord-jdbcsqlite3-adapter["']$/
+ end
+ end
+
def test_generator_if_skip_active_record_is_given
run_generator [destination_root, "--skip-active-record"]
assert_no_file "config/database.yml"
+ assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
assert_file "test/test_helper.rb" do |helper_content|
assert_no_match(/fixtures :all/, helper_content)
end
assert_file "test/performance/browsing_test.rb"
end
- def test_active_record_is_removed_from_frameworks_if_skip_active_record_is_given
- run_generator [destination_root, "--skip-active-record"]
- assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
+ def test_generator_if_skip_active_record_is_given
+ run_generator [destination_root, "--skip-sprockets"]
+ assert_file "config/application.rb" do |content|
+ assert_match(/#\s+require\s+["']sprockets\/railtie["']/, content)
+ assert_no_match(/config\.assets\.enabled = true/, content)
+ end
+ assert_file "test/performance/browsing_test.rb"
end
def test_creation_of_a_test_directory
diff --git a/railties/test/generators/assets_generator_test.rb b/railties/test/generators/assets_generator_test.rb
index 2d20982d04..044e0b6bc6 100644
--- a/railties/test/generators/assets_generator_test.rb
+++ b/railties/test/generators/assets_generator_test.rb
@@ -8,19 +8,13 @@ class AssetsGeneratorTest < Rails::Generators::TestCase
def test_assets
run_generator
- assert_file "app/assets/javascripts/posts.js.coffee"
+ assert_file "app/assets/javascripts/posts.js"
assert_file "app/assets/stylesheets/posts.css"
end
def test_skipping_assets
content = run_generator ["posts", "--no-stylesheets", "--no-javascripts"]
- assert_no_file "app/assets/javascripts/posts.js.coffee"
+ assert_no_file "app/assets/javascripts/posts.js"
assert_no_file "app/assets/stylesheets/posts.css"
end
-
- def test_vanilla_assets
- run_generator ["posts", "--no-javascript-engine"]
- assert_file "app/assets/javascripts/posts.js"
- assert_file "app/assets/stylesheets/posts.css"
- end
end
diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb
index 3adf7be118..c3fa9ebb03 100644
--- a/railties/test/generators/controller_generator_test.rb
+++ b/railties/test/generators/controller_generator_test.rb
@@ -39,7 +39,7 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
def test_invokes_assets
run_generator
- assert_file "app/assets/javascripts/account.js.coffee"
+ assert_file "app/assets/javascripts/account.js"
assert_file "app/assets/stylesheets/account.css"
end
diff --git a/railties/test/generators/generated_attribute_test.rb b/railties/test/generators/generated_attribute_test.rb
index 0d2e624f44..c9f8ab0a7b 100644
--- a/railties/test/generators/generated_attribute_test.rb
+++ b/railties/test/generators/generated_attribute_test.rb
@@ -113,15 +113,8 @@ class GeneratedAttributeTest < Rails::Generators::TestCase
end
end
- def test_nil_type_raises_exception
- assert_raise Thor::Error do
- create_generated_attribute(nil, 'title')
- end
- end
-
- def test_missing_type_raises_exception
- assert_raise Thor::Error do
- create_generated_attribute('', 'title')
- end
+ def test_blank_type_defaults_to_string_raises_exception
+ assert_equal :string, create_generated_attribute(nil, 'title').type
+ assert_equal :string, create_generated_attribute("", 'title').type
end
end
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index 8c5ba9926b..1b0cb425c6 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -12,9 +12,15 @@ class ModelGeneratorTest < Rails::Generators::TestCase
end
def test_model_with_missing_attribute_type
- content = capture(:stderr) { run_generator ["post", "title:string", "body"] }
- assert_match(/Missing type for attribute 'body'/, content)
- assert_match(/Example: 'body:string' where string is the type/, content)
+ run_generator ["post", "title", "body:text", "author"]
+
+ assert_migration "db/migrate/create_posts.rb" do |m|
+ assert_method :change, m do |up|
+ assert_match(/t\.string :title/, up)
+ assert_match(/t\.text :body/, up)
+ assert_match(/t\.string :author/, up)
+ end
+ end
end
def test_invokes_default_orm
diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb
index 17cbac0912..dd1e4bdac1 100644
--- a/railties/test/generators/namespaced_generators_test.rb
+++ b/railties/test/generators/namespaced_generators_test.rb
@@ -7,15 +7,7 @@ require 'rails/generators/rails/scaffold/scaffold_generator'
class NamespacedGeneratorTestCase < Rails::Generators::TestCase
def setup
- TestApp::Application.isolate_namespace(TestApp)
- end
-
- def teardown
- if TestApp.respond_to?(:_railtie)
- TestApp.singleton_class.send(:undef_method, :_railtie)
- TestApp.singleton_class.send(:undef_method, :table_name_prefix)
- TestApp::Application.isolated = false
- end
+ Rails::Generators.namespace = TestApp
end
end
diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb
index 5ffc2501cd..4bd77ff7e3 100644
--- a/railties/test/generators/plugin_new_generator_test.rb
+++ b/railties/test/generators/plugin_new_generator_test.rb
@@ -12,7 +12,6 @@ DEFAULT_PLUGIN_FILES = %w(
lib
lib/bukkits.rb
lib/tasks/bukkits_tasks.rake
- script/rails
test/bukkits_test.rb
test/test_helper.rb
test/dummy
@@ -67,7 +66,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
assert_no_file "test"
end
- def test_database_entry_is_assed_by_default_in_full_mode
+ def test_database_entry_is_generated_for_sqlite3_by_default_in_full_mode
run_generator([destination_root, "--full"])
assert_file "test/dummy/config/database.yml", /sqlite/
assert_file "Gemfile", /^gem\s+["']sqlite3["']$/
@@ -102,19 +101,41 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
def test_skipping_javascripts_without_mountable_option
run_generator
- assert_no_file "app/assets/javascripts/application.js"
+ assert_no_file "app/assets/javascripts/bukkits/application.js"
assert_no_file "vendor/assets/javascripts/jquery.js"
assert_no_file "vendor/assets/javascripts/jquery_ujs.js"
end
def test_javascripts_generation
run_generator [destination_root, "--mountable"]
- assert_file "app/assets/javascripts/application.js"
+ assert_file "app/assets/javascripts/bukkits/application.js"
+ end
+
+ def test_jquery_is_the_default_javascript_library
+ run_generator [destination_root, "--mountable"]
+ assert_file "app/assets/javascripts/bukkits/application.js" do |contents|
+ assert_match %r{^//= require jquery}, contents
+ assert_match %r{^//= require jquery_ujs}, contents
+ end
+ assert_file 'Gemfile' do |contents|
+ assert_match(/^gem 'jquery-rails'/, contents)
+ end
+ end
+
+ def test_other_javascript_libraries
+ run_generator [destination_root, "--mountable", '-j', 'prototype']
+ assert_file "app/assets/javascripts/bukkits/application.js" do |contents|
+ assert_match %r{^//= require prototype}, contents
+ assert_match %r{^//= require prototype_ujs}, contents
+ end
+ assert_file 'Gemfile' do |contents|
+ assert_match(/^gem 'prototype-rails'/, contents)
+ end
end
def test_skip_javascripts
run_generator [destination_root, "--skip-javascript", "--mountable"]
- assert_no_file "app/assets/javascripts/application.js"
+ assert_no_file "app/assets/javascripts/bukkits/application.js"
assert_no_file "vendor/assets/javascripts/jquery.js"
assert_no_file "vendor/assets/javascripts/jquery_ujs.js"
end
@@ -138,18 +159,27 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
assert_match(/1 tests, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`)
end
+ def test_ensure_that_migration_tasks_work_with_mountable_option
+ run_generator [destination_root, "--mountable"]
+ FileUtils.cd destination_root
+ quietly { system 'bundle install' }
+ `bundle exec rake db:migrate`
+ assert_equal 0, $?.exitstatus
+ end
+
def test_creating_engine_in_full_mode
run_generator [destination_root, "--full"]
- assert_file "app/assets/javascripts"
- assert_file "app/assets/stylesheets"
- assert_file "app/assets/images"
+ assert_file "app/assets/javascripts/bukkits"
+ assert_file "app/assets/stylesheets/bukkits"
+ assert_file "app/assets/images/bukkits"
assert_file "app/models"
assert_file "app/controllers"
assert_file "app/views"
assert_file "app/helpers"
assert_file "config/routes.rb", /Rails.application.routes.draw do/
- assert_file "lib/bukkits/engine.rb", /module Bukkits\n class Engine < Rails::Engine\n end\nend/
+ assert_file "lib/bukkits/engine.rb", /module Bukkits\n class Engine < ::Rails::Engine\n end\nend/
assert_file "lib/bukkits.rb", /require "bukkits\/engine"/
+ assert_file "script/rails"
end
def test_being_quiet_while_creating_dummy_application
@@ -158,31 +188,49 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
def test_create_mountable_application_with_mountable_option
run_generator [destination_root, "--mountable"]
- assert_file "app/assets/javascripts"
- assert_file "app/assets/stylesheets"
- assert_file "app/assets/images"
+ assert_file "app/assets/javascripts/bukkits"
+ assert_file "app/assets/stylesheets/bukkits"
+ assert_file "app/assets/images/bukkits"
assert_file "config/routes.rb", /Bukkits::Engine.routes.draw do/
assert_file "lib/bukkits/engine.rb", /isolate_namespace Bukkits/
assert_file "test/dummy/config/routes.rb", /mount Bukkits::Engine => "\/bukkits"/
assert_file "app/controllers/bukkits/application_controller.rb", /module Bukkits\n class ApplicationController < ActionController::Base/
assert_file "app/helpers/bukkits/application_helper.rb", /module Bukkits\n module ApplicationHelper/
- assert_file "app/views/layouts/bukkits/application.html.erb", /<title>Bukkits<\/title>/
+ assert_file "app/views/layouts/bukkits/application.html.erb" do |contents|
+ assert_match "<title>Bukkits</title>", contents
+ assert_match /stylesheet_link_tag\s+['"]bukkits\/application['"]/, contents
+ assert_match /javascript_include_tag\s+['"]bukkits\/application['"]/, contents
+ end
end
def test_creating_gemspec
run_generator
assert_file "bukkits.gemspec", /s.name = "bukkits"/
assert_file "bukkits.gemspec", /s.files = Dir\["\{app,config,lib\}\/\*\*\/\*"\]/
+ assert_file "bukkits.gemspec", /s.test_files = Dir\["test\/\*\*\/\*"\]/
assert_file "bukkits.gemspec", /s.version = "0.0.1"/
end
+ def test_usage_of_engine_commands
+ run_generator [destination_root, "--full"]
+ assert_file "script/rails", /ENGINE_PATH = File.expand_path\('..\/..\/lib\/bukkits\/engine', __FILE__\)/
+ assert_file "script/rails", /ENGINE_ROOT = File.expand_path\('..\/..', __FILE__\)/
+ assert_file "script/rails", /require 'rails\/all'/
+ assert_file "script/rails", /require 'rails\/engine\/commands'/
+ end
+
+ def test_shebang
+ run_generator [destination_root, "--full"]
+ assert_file "script/rails", /#!\/usr\/bin\/env ruby/
+ end
+
def test_passing_dummy_path_as_a_parameter
run_generator [destination_root, "--dummy_path", "spec/dummy"]
assert_file "spec/dummy"
assert_file "spec/dummy/config/application.rb"
assert_no_file "test/dummy"
end
-
+
def test_creating_dummy_without_tests_but_with_dummy_path
run_generator [destination_root, "--dummy_path", "spec/dummy", "--skip-test-unit"]
assert_file "spec/dummy"
@@ -190,6 +238,14 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase
assert_no_file "test"
end
+ def test_skipping_test_unit
+ run_generator [destination_root, "--skip-test-unit"]
+ assert_no_file "test"
+ assert_file "bukkits.gemspec" do |contents|
+ assert_no_match /s.test_files = Dir\["test\/\*\*\/\*"\]/, contents
+ end
+ end
+
def test_skipping_gemspec
run_generator [destination_root, "--skip-gemspec"]
assert_no_file "bukkits.gemspec"
@@ -218,7 +274,6 @@ class CustomPluginGeneratorTest < Rails::Generators::TestCase
assert_file 'spec/dummy'
assert_file 'Rakefile', /task :default => :spec/
assert_file 'Rakefile', /# spec tasks in rakefile/
- assert_file 'script/rails', %r{spec/dummy}
end
protected
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index 2135ffac81..2db8090621 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -81,7 +81,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Assets
assert_file "app/assets/stylesheets/scaffold.css"
- assert_file "app/assets/javascripts/product_lines.js.coffee"
+ assert_file "app/assets/javascripts/product_lines.js"
assert_file "app/assets/stylesheets/product_lines.css"
end
@@ -114,7 +114,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Assets
assert_file "app/assets/stylesheets/scaffold.css", /:visited/
- assert_no_file "app/assets/javascripts/product_lines.js.coffee"
+ assert_no_file "app/assets/javascripts/product_lines.js"
assert_no_file "app/assets/stylesheets/product_lines.css"
end
@@ -190,7 +190,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Assets
assert_file "app/assets/stylesheets/scaffold.css", /:visited/
- assert_file "app/assets/javascripts/admin/roles.js.coffee"
+ assert_file "app/assets/javascripts/admin/roles.js"
assert_file "app/assets/stylesheets/admin/roles.css"
end
@@ -224,7 +224,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Assets
assert_file "app/assets/stylesheets/scaffold.css"
- assert_no_file "app/assets/javascripts/admin/roles.js.coffee"
+ assert_no_file "app/assets/javascripts/admin/roles.js"
assert_no_file "app/assets/stylesheets/admin/roles.css"
end
@@ -246,34 +246,33 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
def test_scaffold_generator_no_assets
run_generator [ "posts", "--no-assets" ]
assert_file "app/assets/stylesheets/scaffold.css"
- assert_no_file "app/assets/javascripts/posts.js.coffee"
+ assert_no_file "app/assets/javascripts/posts.js"
assert_no_file "app/assets/stylesheets/posts.css"
end
def test_scaffold_generator_no_stylesheets
run_generator [ "posts", "--no-stylesheets" ]
assert_no_file "app/assets/stylesheets/scaffold.css"
- assert_file "app/assets/javascripts/posts.js.coffee"
+ assert_file "app/assets/javascripts/posts.js"
assert_no_file "app/assets/stylesheets/posts.css"
end
def test_scaffold_generator_no_javascripts
run_generator [ "posts", "--no-javascripts" ]
assert_file "app/assets/stylesheets/scaffold.css"
- assert_no_file "app/assets/javascripts/posts.js.coffee"
- assert_file "app/assets/stylesheets/posts.css"
- end
-
- def test_scaffold_generator_no_engines
- run_generator [ "posts", "--no-javascript-engine" ]
- assert_file "app/assets/stylesheets/scaffold.css"
- assert_file "app/assets/javascripts/posts.js"
+ assert_no_file "app/assets/javascripts/posts.js"
assert_file "app/assets/stylesheets/posts.css"
end
def test_scaffold_generator_outputs_error_message_on_missing_attribute_type
- content = capture(:stderr) { run_generator ["post", "title:string", "body"]}
- assert_match(/Missing type for attribute 'body'/, content)
- assert_match(/Example: 'body:string' where string is the type/, content)
+ run_generator ["post", "title", "body:text", "author"]
+
+ assert_migration "db/migrate/create_posts.rb" do |m|
+ assert_method :change, m do |up|
+ assert_match(/t\.string :title/, up)
+ assert_match(/t\.text :body/, up)
+ assert_match(/t\.string :author/, up)
+ end
+ end
end
end
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
index be9aef8a41..d3074afd91 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -67,12 +67,12 @@ module SharedGeneratorTests
end
def test_shebang_is_added_to_rails_file
- run_generator [destination_root, "--ruby", "foo/bar/baz"]
+ run_generator [destination_root, "--ruby", "foo/bar/baz", "--full"]
assert_file "script/rails", /#!foo\/bar\/baz/
end
def test_shebang_when_is_the_same_as_default_use_env
- run_generator [destination_root, "--ruby", Thor::Util.ruby_command]
+ run_generator [destination_root, "--ruby", Thor::Util.ruby_command, "--full"]
assert_file "script/rails", /#!\/usr\/bin\/env/
end
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index 301ae80bcf..56329f3183 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -88,12 +88,6 @@ class GeneratorsTest < Rails::Generators::TestCase
assert Rails::Generators.find_by_namespace(:model)
end
- 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_invoke_with_nested_namespaces
model_generator = mock('ModelGenerator') do
expects(:start).with(["Account"], {})
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 69208ce4c3..685d1b154b 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -91,6 +91,9 @@ module TestHelpers
module Generation
# Build an application by invoking the generator and going through the whole stack.
def build_app(options = {})
+ @prev_rails_env = ENV['RAILS_ENV']
+ ENV['RAILS_ENV'] = 'development'
+
FileUtils.rm_rf(app_path)
FileUtils.cp_r(tmp_path('app_template'), app_path)
@@ -115,6 +118,10 @@ module TestHelpers
add_to_config 'config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"; config.session_store :cookie_store, :key => "_myapp_session"; config.active_support.deprecation = :log'
end
+ def teardown_app
+ ENV['RAILS_ENV'] = @prev_rails_env if @prev_rails_env
+ end
+
# Make a very basic app, without creating the whole directory structure.
# This is faster and simpler than the method above.
def make_basic_app
@@ -231,6 +238,10 @@ module TestHelpers
end
end
+ def remove_file(path)
+ FileUtils.rm_rf "#{app_path}/#{path}"
+ end
+
def controller(name, contents)
app_file("app/controllers/#{name}_controller.rb", contents)
end
@@ -280,4 +291,4 @@ Module.new do
end
f.puts "require 'rails/all'"
end
-end
+end unless defined?(RAILS_ISOLATED_ENGINE)
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index b5b21f9ebe..0ff1e0f180 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -15,7 +15,7 @@ module RailtiesTest
@plugin = engine "bukkits" do |plugin|
plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
+ module Bukkits
class Engine < ::Rails::Engine
railtie_name "bukkits"
end
@@ -25,6 +25,10 @@ module RailtiesTest
end
end
+ def teardown
+ teardown_app
+ end
+
test "Rails::Engine itself does not respond to config" do
boot_rails
assert !Rails::Engine.respond_to?(:config)
@@ -32,7 +36,7 @@ module RailtiesTest
test "initializers are executed after application configuration initializers" do
@plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
+ module Bukkits
class Engine < ::Rails::Engine
initializer "dummy_initializer" do
end
@@ -73,7 +77,7 @@ module RailtiesTest
add_to_config("config.action_dispatch.show_exceptions = false")
@plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
+ module Bukkits
class Engine < ::Rails::Engine
endpoint lambda { |env| [200, {'Content-Type' => 'text/html'}, ['Hello World']] }
config.middleware.use ::RailtiesTest::EngineTest::Upcaser
@@ -123,7 +127,7 @@ module RailtiesTest
test "it provides routes as default endpoint" do
@plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
+ module Bukkits
class Engine < ::Rails::Engine
end
end
@@ -149,7 +153,7 @@ module RailtiesTest
test "engine can load its own plugins" do
@plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
+ module Bukkits
class Engine < ::Rails::Engine
end
end
@@ -166,7 +170,7 @@ module RailtiesTest
test "engine does not load plugins that already exists in application" do
@plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
+ module Bukkits
class Engine < ::Rails::Engine
end
end
@@ -189,7 +193,7 @@ module RailtiesTest
test "it loads its environment file" do
@plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
+ module Bukkits
class Engine < ::Rails::Engine
end
end
@@ -208,7 +212,7 @@ module RailtiesTest
test "it passes router in env" do
@plugin.write "lib/bukkits.rb", <<-RUBY
- class Bukkits
+ module Bukkits
class Engine < ::Rails::Engine
endpoint lambda { |env| [200, {'Content-Type' => 'text/html'}, 'hello'] }
end
diff --git a/railties/test/railties/generators_test.rb b/railties/test/railties/generators_test.rb
new file mode 100644
index 0000000000..1d4ba0e5b6
--- /dev/null
+++ b/railties/test/railties/generators_test.rb
@@ -0,0 +1,116 @@
+RAILS_ISOLATED_ENGINE = true
+require "isolation/abstract_unit"
+
+require 'generators/generators_test_helper'
+require "rails/generators/test_case"
+
+module RailtiesTests
+ class GeneratorTest < Rails::Generators::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ TMP_PATH = File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. tmp]))
+ self.destination_root = File.join(TMP_PATH, "foo_bar")
+
+ def tmp_path(*args)
+ File.join(TMP_PATH, *args)
+ end
+
+ def engine_path
+ tmp_path('foo_bar')
+ end
+
+ def bundled_rails(cmd)
+ `bundle exec rails #{cmd}`
+ end
+
+ def rails(cmd)
+ environment = File.expand_path('../../../../load_paths', __FILE__)
+ if File.exist?("#{environment}.rb")
+ require_environment = "-r #{environment}"
+ end
+ `#{Gem.ruby} #{require_environment} #{RAILS_FRAMEWORK_ROOT}/bin/rails #{cmd}`
+ end
+
+ def build_engine(is_mountable=false)
+ FileUtils.rm_rf(engine_path)
+ FileUtils.mkdir_p(engine_path)
+
+ mountable = is_mountable ? "--mountable" : ""
+
+ rails("plugin new #{engine_path} --full #{mountable}")
+
+ Dir.chdir(engine_path) do
+ File.open("Gemfile", "w") do |f|
+ f.write <<-GEMFILE.gsub(/^ {12}/, '')
+ source "http://rubygems.org"
+
+ gem 'rails', :path => '#{RAILS_FRAMEWORK_ROOT}'
+ gem 'sqlite3'
+
+ if RUBY_VERSION < '1.9'
+ gem "ruby-debug", ">= 0.10.3"
+ end
+ GEMFILE
+ end
+ end
+ end
+
+ def build_mountable_engine
+ build_engine(true)
+ end
+
+ def test_controllers_are_correctly_namespaced_when_engine_is_mountable
+ build_mountable_engine
+ Dir.chdir(engine_path) do
+ bundled_rails("g controller topics")
+ assert_file "app/controllers/foo_bar/topics_controller.rb", /module FooBar\n class TopicsController/
+ assert_no_file "app/controllers/topics_controller.rb"
+ end
+ end
+
+ def test_models_are_correctly_namespaced_when_engine_is_mountable
+ build_mountable_engine
+ Dir.chdir(engine_path) do
+ bundled_rails("g model topic")
+ assert_file "app/models/foo_bar/topic.rb", /module FooBar\n class Topic/
+ assert_no_file "app/models/topic.rb"
+ end
+ end
+
+ def test_helpers_are_correctly_namespaced_when_engine_is_mountable
+ build_mountable_engine
+ Dir.chdir(engine_path) do
+ bundled_rails("g helper topics")
+ assert_file "app/helpers/foo_bar/topics_helper.rb", /module FooBar\n module TopicsHelper/
+ assert_no_file "app/helpers/topics_helper.rb"
+ end
+ end
+
+ def test_controllers_are_not_namespaced_when_engine_is_not_mountable
+ build_engine
+ Dir.chdir(engine_path) do
+ bundled_rails("g controller topics")
+ assert_file "app/controllers/topics_controller.rb", /class TopicsController/
+ assert_no_file "app/controllers/foo_bar/topics_controller.rb"
+ end
+ end
+
+ def test_models_are_not_namespaced_when_engine_is_not_mountable
+ build_engine
+ Dir.chdir(engine_path) do
+ bundled_rails("g model topic")
+ assert_file "app/models/topic.rb", /class Topic/
+ assert_no_file "app/models/foo_bar/topic.rb"
+ end
+ end
+
+ def test_helpers_are_not_namespaced_when_engine_is_not_mountable
+ build_engine
+ Dir.chdir(engine_path) do
+ bundled_rails("g helper topics")
+ assert_file "app/helpers/topics_helper.rb", /module TopicsHelper/
+ assert_no_file "app/helpers/foo_bar/topics_helper.rb"
+ end
+ end
+ end
+end
diff --git a/railties/test/railties/mounted_engine_test.rb b/railties/test/railties/mounted_engine_test.rb
index 47a4753e78..b793a7401f 100644
--- a/railties/test/railties/mounted_engine_test.rb
+++ b/railties/test/railties/mounted_engine_test.rb
@@ -106,6 +106,10 @@ module ApplicationTests
boot_rails
end
+ def teardown
+ teardown_app
+ end
+
def app
@app ||= begin
require "#{app_path}/config/environment"
@@ -116,7 +120,7 @@ module ApplicationTests
def reset_script_name!
Rails.application.routes.default_url_options = {}
end
-
+
def script_name(script_name)
Rails.application.routes.default_url_options = {:script_name => script_name}
end
@@ -171,4 +175,3 @@ module ApplicationTests
end
end
end
-
diff --git a/railties/test/railties/plugin_ordering_test.rb b/railties/test/railties/plugin_ordering_test.rb
index f6ca493fdf..1cfaf557e9 100644
--- a/railties/test/railties/plugin_ordering_test.rb
+++ b/railties/test/railties/plugin_ordering_test.rb
@@ -12,6 +12,10 @@ module RailtiesTest
plugin "c_plugin", "$arr << :c"
end
+ def teardown
+ teardown_app
+ end
+
def boot_rails
super
require "#{app_path}/config/environment"
@@ -69,4 +73,4 @@ module RailtiesTest
assert $bar
end
end
-end \ No newline at end of file
+end
diff --git a/railties/test/railties/plugin_test.rb b/railties/test/railties/plugin_test.rb
index c15ac05103..f307d53cf7 100644
--- a/railties/test/railties/plugin_test.rb
+++ b/railties/test/railties/plugin_test.rb
@@ -15,6 +15,10 @@ module RailtiesTest
end
end
+ def teardown
+ teardown_app
+ end
+
test "Rails::Plugin itself does not respond to config" do
boot_rails
assert !Rails::Plugin.respond_to?(:config)
diff --git a/railties/test/railties/railtie_test.rb b/railties/test/railties/railtie_test.rb
index 18fdf59fe3..55f85c7202 100644
--- a/railties/test/railties/railtie_test.rb
+++ b/railties/test/railties/railtie_test.rb
@@ -11,6 +11,10 @@ module RailtiesTest
require "rails/all"
end
+ def teardown
+ teardown_app
+ end
+
def app
@app ||= Rails.application
end
diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb
index 659551d08a..9a64b7c64e 100644
--- a/railties/test/railties/shared_tests.rb
+++ b/railties/test/railties/shared_tests.rb
@@ -53,8 +53,11 @@ module RailtiesTest
add_to_config "ActiveRecord::Base.timestamped_migrations = false"
+ boot_rails
+ railties = Rails.application.railties.all.map(&:railtie_name)
+
Dir.chdir(app_path) do
- output = `rake bukkits:install:migrations`
+ output = `bundle exec rake bukkits:install:migrations`
assert File.exists?("#{app_path}/db/migrate/2_create_users.rb")
assert File.exists?("#{app_path}/db/migrate/3_add_last_name_to_users.rb")
@@ -63,20 +66,33 @@ module RailtiesTest
assert_match /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/, output
assert_equal 3, Dir["#{app_path}/db/migrate/*.rb"].length
- output = `rake railties:install:migrations`
+ output = `bundle exec rake railties:install:migrations`.split("\n")
assert File.exists?("#{app_path}/db/migrate/4_create_yaffles.rb")
- assert_match /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/, output
- assert_match /Copied migration 4_create_yaffles.rb from acts_as_yaffle/, output
- assert_no_match /2_create_users/, output
+ assert_no_match /2_create_users/, output.join("\n")
+
+ yaffle_migration_order = output.index(output.detect{|o| /Copied migration 4_create_yaffles.rb from acts_as_yaffle/ =~ o })
+ bukkits_migration_order = output.index(output.detect{|o| /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/ =~ o })
+ assert_not_nil yaffle_migration_order, "Expected migration to be copied"
+ assert_not_nil bukkits_migration_order, "Expected migration to be skipped"
+ assert_equal (railties.index('acts_as_yaffle') > railties.index('bukkits')) , (yaffle_migration_order > bukkits_migration_order)
migrations_count = Dir["#{app_path}/db/migrate/*.rb"].length
- output = `rake railties:install:migrations`
+ output = `bundle exec rake railties:install:migrations`
assert_equal migrations_count, Dir["#{app_path}/db/migrate/*.rb"].length
end
end
+ def test_no_rake_task_without_migrations
+ boot_rails
+ require 'rake'
+ require 'rdoc/task'
+ require 'rake/testtask'
+ Rails.application.load_tasks
+ assert !Rake::Task.task_defined?('bukkits:install:migrations')
+ end
+
def test_puts_its_lib_directory_on_load_path
boot_rails
require "another"