aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md78
-rw-r--r--README.rdoc77
-rw-r--r--actionpack/CHANGELOG.md2
-rw-r--r--actionpack/lib/action_controller/metal.rb2
-rw-r--r--actionpack/lib/action_dispatch/journey/router.rb4
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb15
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb25
-rw-r--r--actionpack/lib/action_view/helpers/tags/base.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/check_box.rb2
-rw-r--r--actionpack/lib/action_view/helpers/tags/checkable.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb6
-rw-r--r--actionpack/lib/action_view/helpers/tags/collection_helpers.rb6
-rw-r--r--actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb6
-rw-r--r--actionpack/lib/action_view/helpers/tags/collection_select.rb2
-rw-r--r--actionpack/lib/action_view/helpers/tags/color_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/date_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/date_select.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/datetime_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/datetime_local_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/datetime_select.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/email_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/file_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/hidden_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/label.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/month_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/number_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/password_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/radio_button.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/range_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/search_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/select.rb5
-rw-r--r--actionpack/lib/action_view/helpers/tags/tel_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/text_area.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/text_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/time_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/time_select.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/time_zone_select.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/url_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/week_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb13
-rw-r--r--actionpack/lib/action_view/template/resolver.rb2
-rw-r--r--activemodel/CHANGELOG.md21
-rw-r--r--activemodel/README.rdoc14
-rw-r--r--activerecord/CHANGELOG.md34
-rw-r--r--activerecord/lib/active_record/associations.rb4
-rw-r--r--activerecord/lib/active_record/associations/association.rb2
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb4
-rw-r--r--activerecord/lib/active_record/associations/join_dependency/join_part.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/serialization.rb11
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/cast.rb9
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid.rb15
-rw-r--r--activerecord/lib/active_record/connection_handling.rb4
-rw-r--r--activerecord/lib/active_record/core.rb4
-rw-r--r--activerecord/lib/active_record/explain.rb15
-rw-r--r--activerecord/lib/active_record/explain_registry.rb30
-rw-r--r--activerecord/lib/active_record/explain_subscriber.rb5
-rw-r--r--activerecord/lib/active_record/log_subscriber.rb4
-rw-r--r--activerecord/lib/active_record/migration.rb2
-rw-r--r--activerecord/lib/active_record/railties/databases.rake2
-rw-r--r--activerecord/lib/active_record/reflection.rb7
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb3
-rw-r--r--activerecord/lib/active_record/runtime_registry.rb25
-rw-r--r--activerecord/lib/active_record/scoping.rb6
-rw-r--r--activerecord/lib/active_record/statement_cache.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/bytea_test.rb87
-rw-r--r--activerecord/test/cases/adapters/postgresql/datatype_test.rb12
-rw-r--r--activerecord/test/cases/adapters/postgresql/explain_test.rb7
-rw-r--r--activerecord/test/cases/base_test.rb4
-rw-r--r--activerecord/test/cases/explain_subscriber_test.rb59
-rw-r--r--activerecord/test/cases/relation_test.rb2
-rw-r--r--activerecord/test/cases/statement_cache_test.rb8
-rw-r--r--activesupport/CHANGELOG.md16
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/array/uniq_by.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/benchmark.rb7
-rw-r--r--activesupport/lib/active_support/core_ext/module/deprecation.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/string/filters.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/string/inflections.rb2
-rw-r--r--activesupport/lib/active_support/log_subscriber.rb50
-rw-r--r--activesupport/lib/active_support/notifications.rb4
-rw-r--r--activesupport/lib/active_support/per_thread_registry.rb63
-rw-r--r--activesupport/lib/active_support/subscriber.rb75
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb3
-rw-r--r--activesupport/test/ordered_hash_test.rb6
-rw-r--r--guides/assets/images/getting_started/unknown_action_create_for_posts.pngbin31314 -> 17698 bytes
-rw-r--r--guides/rails_guides/markdown/renderer.rb2
-rw-r--r--guides/source/4_0_release_notes.md2
-rw-r--r--guides/source/action_controller_overview.md27
-rw-r--r--guides/source/action_mailer_basics.md25
-rw-r--r--guides/source/action_view_overview.md9
-rw-r--r--guides/source/active_record_basics.md193
-rw-r--r--guides/source/asset_pipeline.md30
-rw-r--r--guides/source/caching_with_rails.md4
-rw-r--r--guides/source/command_line.md4
-rw-r--r--guides/source/configuring.md2
-rw-r--r--guides/source/credits.html.erb2
-rw-r--r--guides/source/debugging_rails_applications.md13
-rw-r--r--guides/source/development_dependencies_install.md4
-rw-r--r--guides/source/documents.yaml5
-rw-r--r--guides/source/engines.md28
-rw-r--r--guides/source/form_helpers.md7
-rw-r--r--guides/source/getting_started.md17
-rw-r--r--guides/source/i18n.md22
-rw-r--r--guides/source/layouts_and_rendering.md59
-rw-r--r--guides/source/rails_application_templates.md22
-rw-r--r--guides/source/rails_on_rack.md15
-rw-r--r--guides/source/routing.md6
-rw-r--r--guides/source/security.md2
-rw-r--r--guides/source/testing.md14
-rw-r--r--guides/source/upgrading_ruby_on_rails.md4
-rw-r--r--rails.gemspec2
-rw-r--r--railties/CHANGELOG.md2
-rw-r--r--railties/lib/rails/app_rails_loader.rb55
-rw-r--r--railties/lib/rails/generators/app_base.rb26
-rw-r--r--railties/test/app_rails_loader_test.rb80
-rw-r--r--railties/test/application/initializers/load_path_test.rb1
-rw-r--r--railties/test/application/rake_test.rb17
118 files changed, 1015 insertions, 695 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..45c50a1708
--- /dev/null
+++ b/README.md
@@ -0,0 +1,78 @@
+## Welcome to Rails
+
+Rails is a web-application framework that includes everything needed to
+create database-backed web applications according to the
+[Model-View-Controller (MVC)](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)
+pattern.
+
+Understanding the MVC pattern is key to understanding Rails. MVC divides your
+application into three layers, each with a specific responsibility.
+
+The _View layer_ is composed of "templates" that are responsible for providing
+appropriate representations of your application's resources. Templates can
+come in a variety of formats, but most view templates are HTML with embedded
+Ruby code (ERB files).
+
+The _Model layer_ represents your domain model (such as Account, Product,
+Person, Post, etc.) and encapsulates the business logic that is specific to
+your application. In Rails, database-backed model classes are derived from
+`ActiveRecord::Base`. Active Record allows you to present the data from
+database rows as objects and embellish these data objects with business logic
+methods. Although most Rails models are backed by a database, models can also
+be ordinary Ruby classes, or Ruby classes that implement a set of interfaces
+as provided by the Active Model module. You can read more about Active Record
+in its [README](link:/activerecord/README.rdoc).
+
+The _Controller layer_ is responsible for handling incoming HTTP requests and
+providing a suitable response. Usually this means returning HTML, but Rails
+controllers can also generate XML, JSON, PDFs, mobile-specific views, and
+more. Controllers manipulate models and render view templates in order to
+generate the appropriate HTTP response.
+
+In Rails, the Controller and View layers are handled together by Action Pack.
+These two layers are bundled in a single package due to their heavy interdependence.
+This is unlike the relationship between Active Record and Action Pack, which are
+independent. Each of these packages can be used independently outside of Rails. You
+can read more about Action Pack in its [README](link:/actionpack/README.rdoc).
+
+## Getting Started
+
+1. Install Rails at the command prompt if you haven't yet:
+
+ gem install rails
+
+2. At the command prompt, create a new Rails application:
+
+ rails new myapp
+
+ where "myapp" is the application name.
+
+3. Change directory to `myapp` and start the web server:
+
+ cd myapp
+ rails server
+
+ Run with `--help` or `-h` for options.
+
+4. Go to http://localhost:3000 and you'll see: "Welcome aboard: You're riding Ruby on Rails!"
+
+5. Follow the guidelines to start developing your application. You may find
+ the following resources handy:
+ * [Getting Started with Rails](http://guides.rubyonrails.org/getting_started.html)
+ * [Ruby on Rails Guides](http://guides.rubyonrails.org)
+ * [The API Documentation](http://api.rubyonrails.org)
+ * [Ruby on Rails Tutorial](http://ruby.railstutorial.org/ruby-on-rails-tutorial-book)
+
+## Contributing
+
+We encourage you to contribute to Ruby on Rails! Please check out the
+[Contributing to Ruby on Rails guide](http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html) for guidelines about how to proceed. [Join us!](http://contributors.rubyonrails.org)
+
+## Code Status
+
+* [![Build Status](https://secure.travis-ci.org/rails/rails.png)](http://travis-ci.org/rails/rails)
+* [![Dependencies](https://gemnasium.com/rails/rails.png?travis)](https://gemnasium.com/rails/rails)
+
+## License
+
+Ruby on Rails is released under the [MIT License](http://www.opensource.org/licenses/MIT).
diff --git a/README.rdoc b/README.rdoc
deleted file mode 100644
index 55b5efc916..0000000000
--- a/README.rdoc
+++ /dev/null
@@ -1,77 +0,0 @@
-== Welcome to Rails
-
-Rails is a web-application framework that includes everything needed to create
-database-backed web applications according to the {Model-View-Controller (MVC)}[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller] pattern.
-
-Understanding the MVC pattern is key to understanding Rails. MVC divides your application
-into three layers, each with a specific responsibility.
-
-The View layer is composed of "templates" that are responsible for providing
-appropriate representations of your application's resources. Templates
-can come in a variety of formats, but most view templates are \HTML with embedded Ruby
-code (.erb files).
-
-The Model layer represents your domain model (such as Account, Product, Person, Post)
-and encapsulates the business logic that is specific to your application. In Rails,
-database-backed model classes are derived from ActiveRecord::Base. Active Record allows
-you to present the data from database rows as objects and embellish these data objects
-with business logic methods. Although most Rails models are backed by a database, models
-can also be ordinary Ruby classes, or Ruby classes that implement a set of interfaces as
-provided by the ActiveModel module. You can read more about Active Record in its
-{README}[link:/activerecord/README.rdoc].
-
-The Controller layer is responsible for handling incoming HTTP requests and providing a
-suitable response. Usually this means returning \HTML, but Rails controllers can also
-generate XML, JSON, PDFs, mobile-specific views, and more. Controllers manipulate models
-and render view templates in order to generate the appropriate HTTP response.
-
-In Rails, the Controller and View layers are handled together by Action Pack.
-These two layers are bundled in a single package due to their heavy interdependence.
-This is unlike the relationship between Active Record and Action Pack, which are
-independent. Each of these packages can be used independently outside of Rails. You
-can read more about Action Pack in its {README}[link:/actionpack/README.rdoc].
-
-== Getting Started
-
-1. Install Rails at the command prompt if you haven't yet:
-
- gem install rails
-
-2. At the command prompt, create a new Rails application:
-
- rails new myapp
-
- where "myapp" is the application name.
-
-3. Change directory to +myapp+ and start the web server:
-
- cd myapp; rails server
-
- Run with <tt>--help</tt> or <tt>-h</tt> for options.
-
-4. Go to http://localhost:3000 and you'll see:
-
- "Welcome aboard: You're riding Ruby on Rails!"
-
-5. Follow the guidelines to start developing your application. You may find the following resources handy:
-
-* The README file created within your application.
-* {Getting Started with Rails}[http://guides.rubyonrails.org/getting_started.html].
-* {Ruby on Rails Tutorial}[http://ruby.railstutorial.org/ruby-on-rails-tutorial-book].
-* {Ruby on Rails Guides}[http://guides.rubyonrails.org].
-* {The API Documentation}[http://api.rubyonrails.org].
-
-== Contributing
-
-We encourage you to contribute to Ruby on Rails! Please check out the {Contributing to Rails
-guide}[http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html] for guidelines about how
-to proceed. {Join us}[http://contributors.rubyonrails.org]!
-
-== Code Status
-
-* {<img src="https://secure.travis-ci.org/rails/rails.png"/>}[http://travis-ci.org/rails/rails]
-* {<img src="https://gemnasium.com/rails/rails.png?travis"/>}[https://gemnasium.com/rails/rails]
-
-== License
-
-Ruby on Rails is released under the {MIT License}[http://www.opensource.org/licenses/MIT].
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 9106ec6ef4..06e05e4525 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -69,7 +69,7 @@
*Brad Dunbar*
* Include I18n locale fallbacks in view lookup.
- Fixes GH#3512.
+ Fixes #3512.
*Juan Barreneche*
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index 143b3e0cbd..c7cb88e64f 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -57,7 +57,7 @@ module ActionController
# And then to route requests to your metal controller, you would add
# something like this to <tt>config/routes.rb</tt>:
#
- # match 'hello', to: HelloController.action(:index)
+ # get 'hello', to: HelloController.action(:index)
#
# The +action+ method returns a valid Rack application for the \Rails
# router to dispatch to.
diff --git a/actionpack/lib/action_dispatch/journey/router.rb b/actionpack/lib/action_dispatch/journey/router.rb
index 31868b1814..419e665d12 100644
--- a/actionpack/lib/action_dispatch/journey/router.rb
+++ b/actionpack/lib/action_dispatch/journey/router.rb
@@ -38,7 +38,9 @@ module ActionDispatch
env['REMOTE_ADDR']
end
- def [](k); env[k]; end
+ def [](k)
+ env[k]
+ end
end
attr_reader :request_class, :formatter
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 521eaf25d2..693b6bdfcc 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -14,7 +14,6 @@ module ActionView
# # => <img alt="Rails" src="/assets/rails.png" />
# stylesheet_link_tag("application")
# # => <link href="/assets/application.css?body=1" media="screen" rel="stylesheet" />
- #
module AssetTagHelper
extend ActiveSupport::Concern
@@ -50,7 +49,6 @@ module ActionView
#
# javascript_include_tag "http://www.example.com/xmlhr.js"
# # => <script src="http://www.example.com/xmlhr.js"></script>
- #
def javascript_include_tag(*sources)
options = sources.extract_options!.stringify_keys
path_options = options.extract!('protocol').symbolize_keys
@@ -67,7 +65,7 @@ module ActionView
# you don't specify an extension, <tt>.css</tt> will be appended automatically.
# You can modify the link attributes by passing a hash as the last argument.
# For historical reasons, the 'media' attribute will always be present and defaults
- # to "screen", so you must explicitely set it to "all" for the stylesheet(s) to
+ # to "screen", so you must explicitly set it to "all" for the stylesheet(s) to
# apply to all media types.
#
# stylesheet_link_tag "style"
@@ -88,7 +86,6 @@ module ActionView
# stylesheet_link_tag "random.styles", "/css/stylish"
# # => <link href="/assets/random.styles" media="screen" rel="stylesheet" />
# # <link href="/css/stylish.css" media="screen" rel="stylesheet" />
- #
def stylesheet_link_tag(*sources)
options = sources.extract_options!.stringify_keys
path_options = options.extract!('protocol').symbolize_keys
@@ -109,10 +106,13 @@ module ActionView
# +url_options+. You can modify the LINK tag itself in +tag_options+.
#
# ==== Options
+ #
# * <tt>:rel</tt> - Specify the relation of this link, defaults to "alternate"
# * <tt>:type</tt> - Override the auto-generated mime type
# * <tt>:title</tt> - Specify the title of the link, defaults to the +type+
#
+ # ==== Examples
+ #
# auto_discovery_link_tag
# # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/action" />
# auto_discovery_link_tag(:atom)
@@ -148,9 +148,12 @@ module ActionView
# you can override "rel" and "type".
#
# ==== Options
+ #
# * <tt>:rel</tt> - Specify the relation of this link, defaults to 'shortcut icon'
# * <tt>:type</tt> - Override the auto-generated mime type, defaults to 'image/vnd.microsoft.icon'
#
+ # ==== Examples
+ #
# favicon_link_tag '/myicon.ico'
# # => <link href="/assets/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
#
@@ -160,7 +163,6 @@ module ActionView
#
# favicon_link_tag '/mb-icon.png', rel: 'apple-touch-icon', type: 'image/png'
# # => <link href="/assets/mb-icon.png" rel="apple-touch-icon" type="image/png" />
- #
def favicon_link_tag(source='favicon.ico', options={})
tag('link', {
:rel => 'shortcut icon',
@@ -173,6 +175,7 @@ module ActionView
# path or a file.
#
# ==== Options
+ #
# You can add HTML attributes using the +options+. The +options+ supports
# three additional keys for convenience and conformance:
#
@@ -250,6 +253,8 @@ module ActionView
# width="30" and height="45". <tt>:size</tt> will be ignored if the
# value is not in the correct format.
#
+ # ==== Examples
+ #
# video_tag("trailer")
# # => <video src="/videos/trailer" />
# video_tag("trailer.ogg")
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index 9e1be65b1a..fda7038a5d 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -28,6 +28,8 @@ module ActionView
# Formats a +number+ into a US phone number (e.g., (555)
# 123-9876). You can customize the format in the +options+ hash.
#
+ # ==== Options
+ #
# * <tt>:area_code</tt> - Adds parentheses around the area code.
# * <tt>:delimiter</tt> - Specifies the delimiter to use
# (defaults to "-").
@@ -38,6 +40,8 @@ module ActionView
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
# the argument is invalid.
#
+ # ==== Examples
+ #
# number_to_phone(5551234) # => 555-1234
# number_to_phone("5551234") # => 555-1234
# number_to_phone(1235551234) # => 123-555-1234
@@ -61,6 +65,8 @@ module ActionView
# Formats a +number+ into a currency string (e.g., $13.65). You
# can customize the format in the +options+ hash.
#
+ # ==== Options
+ #
# * <tt>:locale</tt> - Sets the locale to be used for formatting
# (defaults to current locale).
# * <tt>:precision</tt> - Sets the level of precision (defaults
@@ -82,6 +88,8 @@ module ActionView
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
# the argument is invalid.
#
+ # ==== Examples
+ #
# number_to_currency(1234567890.50) # => $1,234,567,890.50
# number_to_currency(1234567890.506) # => $1,234,567,890.51
# number_to_currency(1234567890.506, precision: 3) # => $1,234,567,890.506
@@ -108,6 +116,7 @@ module ActionView
# Formats a +number+ as a percentage string (e.g., 65%). You can
# customize the format in the +options+ hash.
#
+ # ==== Options
#
# * <tt>:locale</tt> - Sets the locale to be used for formatting
# (defaults to current locale).
@@ -128,6 +137,8 @@ module ActionView
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
# the argument is invalid.
#
+ # ==== Examples
+ #
# number_to_percentage(100) # => 100.000%
# number_to_percentage("98") # => 98.000%
# number_to_percentage(100, precision: 0) # => 100%
@@ -151,6 +162,8 @@ module ActionView
# (e.g., 12,324). You can customize the format in the +options+
# hash.
#
+ # ==== Options
+ #
# * <tt>:locale</tt> - Sets the locale to be used for formatting
# (defaults to current locale).
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
@@ -160,6 +173,8 @@ module ActionView
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
# the argument is invalid.
#
+ # ==== Examples
+ #
# number_with_delimiter(12345678) # => 12,345,678
# number_with_delimiter("123456") # => 123,456
# number_with_delimiter(12345678.05) # => 12,345,678.05
@@ -185,6 +200,8 @@ module ActionView
# +:significant+ is +false+, and 5 if +:significant+ is +true+).
# You can customize the format in the +options+ hash.
#
+ # ==== Options
+ #
# * <tt>:locale</tt> - Sets the locale to be used for formatting
# (defaults to current locale).
# * <tt>:precision</tt> - Sets the precision of the number
@@ -202,6 +219,8 @@ module ActionView
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
# the argument is invalid.
#
+ # ==== Examples
+ #
# number_with_precision(111.2345) # => 111.235
# number_with_precision(111.2345, precision: 2) # => 111.23
# number_with_precision(13, precision: 5) # => 13.00000
@@ -233,6 +252,8 @@ module ActionView
# See <tt>number_to_human</tt> if you want to pretty-print a
# generic number.
#
+ # ==== Options
+ #
# * <tt>:locale</tt> - Sets the locale to be used for formatting
# (defaults to current locale).
# * <tt>:precision</tt> - Sets the precision of the number
@@ -252,6 +273,8 @@ module ActionView
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
# the argument is invalid.
#
+ # ==== Examples
+ #
# number_to_human_size(123) # => 123 Bytes
# number_to_human_size(1234) # => 1.21 KB
# number_to_human_size(12345) # => 12.1 KB
@@ -324,6 +347,8 @@ module ActionView
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
# the argument is invalid.
#
+ # ==== Examples
+ #
# number_to_human(123) # => "123"
# number_to_human(1234) # => "1.23 Thousand"
# number_to_human(12345) # => "12.3 Thousand"
diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb
index 10dec66b4f..3fe3f4e9df 100644
--- a/actionpack/lib/action_view/helpers/tags/base.rb
+++ b/actionpack/lib/action_view/helpers/tags/base.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class Base #:nodoc:
+ module Tags # :nodoc:
+ class Base # :nodoc:
include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper
include FormOptionsHelper
diff --git a/actionpack/lib/action_view/helpers/tags/check_box.rb b/actionpack/lib/action_view/helpers/tags/check_box.rb
index e21cc07746..6d51f2629a 100644
--- a/actionpack/lib/action_view/helpers/tags/check_box.rb
+++ b/actionpack/lib/action_view/helpers/tags/check_box.rb
@@ -2,7 +2,7 @@ require 'action_view/helpers/tags/checkable'
module ActionView
module Helpers
- module Tags
+ module Tags # :nodoc:
class CheckBox < Base #:nodoc:
include Checkable
diff --git a/actionpack/lib/action_view/helpers/tags/checkable.rb b/actionpack/lib/action_view/helpers/tags/checkable.rb
index b97c0c68d7..052e9df662 100644
--- a/actionpack/lib/action_view/helpers/tags/checkable.rb
+++ b/actionpack/lib/action_view/helpers/tags/checkable.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- module Checkable
+ module Tags # :nodoc:
+ module Checkable # :nodoc:
def input_checked?(object, options)
if options.has_key?("checked")
checked = options.delete "checked"
diff --git a/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb b/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb
index 9655008fe2..52006d856b 100644
--- a/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb
+++ b/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb
@@ -2,11 +2,11 @@ require 'action_view/helpers/tags/collection_helpers'
module ActionView
module Helpers
- module Tags
- class CollectionCheckBoxes < Base
+ module Tags # :nodoc:
+ class CollectionCheckBoxes < Base # :nodoc:
include CollectionHelpers
- class CheckBoxBuilder < Builder
+ class CheckBoxBuilder < Builder # :nodoc:
def check_box(extra_html_options={})
html_options = extra_html_options.merge(@input_html_options)
@template_object.check_box(@object_name, @method_name, html_options, @value, nil)
diff --git a/actionpack/lib/action_view/helpers/tags/collection_helpers.rb b/actionpack/lib/action_view/helpers/tags/collection_helpers.rb
index e92a318c73..cd12ddaf65 100644
--- a/actionpack/lib/action_view/helpers/tags/collection_helpers.rb
+++ b/actionpack/lib/action_view/helpers/tags/collection_helpers.rb
@@ -1,8 +1,8 @@
module ActionView
module Helpers
- module Tags
- module CollectionHelpers
- class Builder
+ module Tags # :nodoc:
+ module CollectionHelpers # :nodoc:
+ class Builder # :nodoc:
attr_reader :object, :text, :value
def initialize(template_object, object_name, method_name, object,
diff --git a/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb b/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb
index 893f4411e7..20be34c1f2 100644
--- a/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb
+++ b/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb
@@ -2,11 +2,11 @@ require 'action_view/helpers/tags/collection_helpers'
module ActionView
module Helpers
- module Tags
- class CollectionRadioButtons < Base
+ module Tags # :nodoc:
+ class CollectionRadioButtons < Base # :nodoc:
include CollectionHelpers
- class RadioButtonBuilder < Builder
+ class RadioButtonBuilder < Builder # :nodoc:
def radio_button(extra_html_options={})
html_options = extra_html_options.merge(@input_html_options)
@template_object.radio_button(@object_name, @method_name, @value, html_options)
diff --git a/actionpack/lib/action_view/helpers/tags/collection_select.rb b/actionpack/lib/action_view/helpers/tags/collection_select.rb
index ec78e6e5f9..6cb2b2e0d3 100644
--- a/actionpack/lib/action_view/helpers/tags/collection_select.rb
+++ b/actionpack/lib/action_view/helpers/tags/collection_select.rb
@@ -1,6 +1,6 @@
module ActionView
module Helpers
- module Tags
+ module Tags # :nodoc:
class CollectionSelect < Base #:nodoc:
def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options)
@collection = collection
diff --git a/actionpack/lib/action_view/helpers/tags/color_field.rb b/actionpack/lib/action_view/helpers/tags/color_field.rb
index 6f08f8483a..d8fc797035 100644
--- a/actionpack/lib/action_view/helpers/tags/color_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/color_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class ColorField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class ColorField < TextField # :nodoc:
def render
options = @options.stringify_keys
options["value"] = @options.fetch("value") { validate_color_string(value(object)) }
diff --git a/actionpack/lib/action_view/helpers/tags/date_field.rb b/actionpack/lib/action_view/helpers/tags/date_field.rb
index 64c29dea3d..c22be0db29 100644
--- a/actionpack/lib/action_view/helpers/tags/date_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/date_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class DateField < DatetimeField #:nodoc:
+ module Tags # :nodoc:
+ class DateField < DatetimeField # :nodoc:
private
def format_date(value)
diff --git a/actionpack/lib/action_view/helpers/tags/date_select.rb b/actionpack/lib/action_view/helpers/tags/date_select.rb
index 734591394b..0c4ac40070 100644
--- a/actionpack/lib/action_view/helpers/tags/date_select.rb
+++ b/actionpack/lib/action_view/helpers/tags/date_select.rb
@@ -2,8 +2,8 @@ require 'active_support/core_ext/time/calculations'
module ActionView
module Helpers
- module Tags
- class DateSelect < Base #:nodoc:
+ module Tags # :nodoc:
+ class DateSelect < Base # :nodoc:
def initialize(object_name, method_name, template_object, options, html_options)
@html_options = html_options
diff --git a/actionpack/lib/action_view/helpers/tags/datetime_field.rb b/actionpack/lib/action_view/helpers/tags/datetime_field.rb
index e407146e96..9a2279c611 100644
--- a/actionpack/lib/action_view/helpers/tags/datetime_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/datetime_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class DatetimeField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class DatetimeField < TextField # :nodoc:
def render
options = @options.stringify_keys
options["value"] = @options.fetch("value") { format_date(value(object)) }
diff --git a/actionpack/lib/action_view/helpers/tags/datetime_local_field.rb b/actionpack/lib/action_view/helpers/tags/datetime_local_field.rb
index 6668d6d718..b4a74185d1 100644
--- a/actionpack/lib/action_view/helpers/tags/datetime_local_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/datetime_local_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class DatetimeLocalField < DatetimeField #:nodoc:
+ module Tags # :nodoc:
+ class DatetimeLocalField < DatetimeField # :nodoc:
class << self
def field_type
@field_type ||= "datetime-local"
diff --git a/actionpack/lib/action_view/helpers/tags/datetime_select.rb b/actionpack/lib/action_view/helpers/tags/datetime_select.rb
index a32c840bce..563de1840e 100644
--- a/actionpack/lib/action_view/helpers/tags/datetime_select.rb
+++ b/actionpack/lib/action_view/helpers/tags/datetime_select.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class DatetimeSelect < DateSelect #:nodoc:
+ module Tags # :nodoc:
+ class DatetimeSelect < DateSelect # :nodoc:
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/email_field.rb b/actionpack/lib/action_view/helpers/tags/email_field.rb
index 45cde507d7..7ce3ccb9bf 100644
--- a/actionpack/lib/action_view/helpers/tags/email_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/email_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class EmailField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class EmailField < TextField # :nodoc:
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/file_field.rb b/actionpack/lib/action_view/helpers/tags/file_field.rb
index 59f2ff71b4..476b820d84 100644
--- a/actionpack/lib/action_view/helpers/tags/file_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/file_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class FileField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class FileField < TextField # :nodoc:
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb b/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb
index 507ba8835f..2ed4712dac 100644
--- a/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb
+++ b/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class GroupedCollectionSelect < Base #:nodoc:
+ module Tags # :nodoc:
+ class GroupedCollectionSelect < Base # :nodoc:
def initialize(object_name, method_name, template_object, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options)
@collection = collection
@group_method = group_method
diff --git a/actionpack/lib/action_view/helpers/tags/hidden_field.rb b/actionpack/lib/action_view/helpers/tags/hidden_field.rb
index a8d13dc1b1..c3757c2461 100644
--- a/actionpack/lib/action_view/helpers/tags/hidden_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/hidden_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class HiddenField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class HiddenField < TextField # :nodoc:
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/label.rb b/actionpack/lib/action_view/helpers/tags/label.rb
index 16135fcd5a..35d3ba8434 100644
--- a/actionpack/lib/action_view/helpers/tags/label.rb
+++ b/actionpack/lib/action_view/helpers/tags/label.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class Label < Base #:nodoc:
+ module Tags # :nodoc:
+ class Label < Base # :nodoc:
def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil)
options ||= {}
diff --git a/actionpack/lib/action_view/helpers/tags/month_field.rb b/actionpack/lib/action_view/helpers/tags/month_field.rb
index 3d3c32d847..4c0fb846ee 100644
--- a/actionpack/lib/action_view/helpers/tags/month_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/month_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class MonthField < DatetimeField #:nodoc:
+ module Tags # :nodoc:
+ class MonthField < DatetimeField # :nodoc:
private
def format_date(value)
diff --git a/actionpack/lib/action_view/helpers/tags/number_field.rb b/actionpack/lib/action_view/helpers/tags/number_field.rb
index 9cd04434f0..4f95b1b4de 100644
--- a/actionpack/lib/action_view/helpers/tags/number_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/number_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class NumberField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class NumberField < TextField # :nodoc:
def render
options = @options.stringify_keys
diff --git a/actionpack/lib/action_view/helpers/tags/password_field.rb b/actionpack/lib/action_view/helpers/tags/password_field.rb
index 6e7a4d3c36..6099fa6f19 100644
--- a/actionpack/lib/action_view/helpers/tags/password_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/password_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class PasswordField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class PasswordField < TextField # :nodoc:
def render
@options = {:value => nil}.merge!(@options)
super
diff --git a/actionpack/lib/action_view/helpers/tags/radio_button.rb b/actionpack/lib/action_view/helpers/tags/radio_button.rb
index 8a0421f061..4849c537a5 100644
--- a/actionpack/lib/action_view/helpers/tags/radio_button.rb
+++ b/actionpack/lib/action_view/helpers/tags/radio_button.rb
@@ -2,8 +2,8 @@ require 'action_view/helpers/tags/checkable'
module ActionView
module Helpers
- module Tags
- class RadioButton < Base #:nodoc:
+ module Tags # :nodoc:
+ class RadioButton < Base # :nodoc:
include Checkable
def initialize(object_name, method_name, template_object, tag_value, options)
diff --git a/actionpack/lib/action_view/helpers/tags/range_field.rb b/actionpack/lib/action_view/helpers/tags/range_field.rb
index 47db4680e7..f98ae88043 100644
--- a/actionpack/lib/action_view/helpers/tags/range_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/range_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class RangeField < NumberField #:nodoc:
+ module Tags # :nodoc:
+ class RangeField < NumberField # :nodoc:
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/search_field.rb b/actionpack/lib/action_view/helpers/tags/search_field.rb
index 818fd4b887..c09e2f1be7 100644
--- a/actionpack/lib/action_view/helpers/tags/search_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/search_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class SearchField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class SearchField < TextField # :nodoc:
def render
options = @options.stringify_keys
diff --git a/actionpack/lib/action_view/helpers/tags/select.rb b/actionpack/lib/action_view/helpers/tags/select.rb
index 53a108b7e6..d64e2f68ef 100644
--- a/actionpack/lib/action_view/helpers/tags/select.rb
+++ b/actionpack/lib/action_view/helpers/tags/select.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class Select < Base #:nodoc:
+ module Tags # :nodoc:
+ class Select < Base # :nodoc:
def initialize(object_name, method_name, template_object, choices, options, html_options)
@choices = choices
@choices = @choices.to_a if @choices.is_a?(Range)
@@ -31,7 +31,6 @@ module ActionView
#
# [nil, []]
# { nil => [] }
- #
def grouped_choices?
!@choices.empty? && @choices.first.respond_to?(:last) && Array === @choices.first.last
end
diff --git a/actionpack/lib/action_view/helpers/tags/tel_field.rb b/actionpack/lib/action_view/helpers/tags/tel_field.rb
index 87c1f6b6b6..987bb9e67a 100644
--- a/actionpack/lib/action_view/helpers/tags/tel_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/tel_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class TelField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class TelField < TextField # :nodoc:
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/text_area.rb b/actionpack/lib/action_view/helpers/tags/text_area.rb
index f74652c5e7..c81156c0c8 100644
--- a/actionpack/lib/action_view/helpers/tags/text_area.rb
+++ b/actionpack/lib/action_view/helpers/tags/text_area.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class TextArea < Base #:nodoc:
+ module Tags # :nodoc:
+ class TextArea < Base # :nodoc:
def render
options = @options.stringify_keys
add_default_name_and_id(options)
diff --git a/actionpack/lib/action_view/helpers/tags/text_field.rb b/actionpack/lib/action_view/helpers/tags/text_field.rb
index 024a1a8af2..baa5ff768e 100644
--- a/actionpack/lib/action_view/helpers/tags/text_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/text_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class TextField < Base #:nodoc:
+ module Tags # :nodoc:
+ class TextField < Base # :nodoc:
def render
options = @options.stringify_keys
options["size"] = options["maxlength"] unless options.key?("size")
diff --git a/actionpack/lib/action_view/helpers/tags/time_field.rb b/actionpack/lib/action_view/helpers/tags/time_field.rb
index a3941860c9..0e90a3aed7 100644
--- a/actionpack/lib/action_view/helpers/tags/time_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/time_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class TimeField < DatetimeField #:nodoc:
+ module Tags # :nodoc:
+ class TimeField < DatetimeField # :nodoc:
private
def format_date(value)
diff --git a/actionpack/lib/action_view/helpers/tags/time_select.rb b/actionpack/lib/action_view/helpers/tags/time_select.rb
index 9e97deb706..0b06311d25 100644
--- a/actionpack/lib/action_view/helpers/tags/time_select.rb
+++ b/actionpack/lib/action_view/helpers/tags/time_select.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class TimeSelect < DateSelect #:nodoc:
+ module Tags # :nodoc:
+ class TimeSelect < DateSelect # :nodoc:
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/time_zone_select.rb b/actionpack/lib/action_view/helpers/tags/time_zone_select.rb
index 0a176157c3..80d165ec7e 100644
--- a/actionpack/lib/action_view/helpers/tags/time_zone_select.rb
+++ b/actionpack/lib/action_view/helpers/tags/time_zone_select.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class TimeZoneSelect < Base #:nodoc:
+ module Tags # :nodoc:
+ class TimeZoneSelect < Base # :nodoc:
def initialize(object_name, method_name, template_object, priority_zones, options, html_options)
@priority_zones = priority_zones
@html_options = html_options
diff --git a/actionpack/lib/action_view/helpers/tags/url_field.rb b/actionpack/lib/action_view/helpers/tags/url_field.rb
index 1ffdfe0b3c..d76340178d 100644
--- a/actionpack/lib/action_view/helpers/tags/url_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/url_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class UrlField < TextField #:nodoc:
+ module Tags # :nodoc:
+ class UrlField < TextField # :nodoc:
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/week_field.rb b/actionpack/lib/action_view/helpers/tags/week_field.rb
index 1e13939a0a..5b3d0494e9 100644
--- a/actionpack/lib/action_view/helpers/tags/week_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/week_field.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers
- module Tags
- class WeekField < DatetimeField #:nodoc:
+ module Tags # :nodoc:
+ class WeekField < DatetimeField # :nodoc:
private
def format_date(value)
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 2e124cf085..147f9fd8ed 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -126,8 +126,8 @@ module ActionView
# Extracts an excerpt from +text+ that matches the first instance of +phrase+.
# The <tt>:radius</tt> option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters
# defined in <tt>:radius</tt> (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+,
- # then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly. The
- # <tt>:separator</tt> enable to choose the delimation. The resulting string will be stripped in any case. If the +phrase+
+ # then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly. Use the
+ # <tt>:separator</tt> option to choose the delimitation. The resulting string will be stripped in any case. If the +phrase+
# isn't found, nil is returned.
#
# excerpt('This is an example', 'an', radius: 5)
@@ -145,7 +145,7 @@ module ActionView
# excerpt('This is also an example', 'an', radius: 8, omission: '<chop> ')
# # => <chop> is also an example
#
- # excerpt('This is a very beautiful morning', 'very', separator: ' ', radius: 1)
+ # excerpt('This is a very beautiful morning', 'very', separator: ' ', radius: 1)
# # => ...a very beautiful...
def excerpt(text, phrase, options = {})
return unless text && phrase
@@ -250,8 +250,11 @@ module ActionView
# simple_format("Look ma! A class!", class: 'description')
# # => "<p class='description'>Look ma! A class!</p>"
#
- # simple_format("<span>I'm allowed!</span> It's true.", {}, sanitize: false)
- # # => "<p><span>I'm allowed!</span> It's true.</p>"
+ # simple_format("<blink>Unblinkable.</blink>")
+ # # => "<p>Unblinkable.</p>"
+ #
+ # simple_format("<blink>Blinkable!</blink> It's true.", {}, sanitize: false)
+ # # => "<p><blink>Blinkable!</span> It's true.</p>"
def simple_format(text, html_options = {}, options = {})
wrapper_tag = options.fetch(:wrapper_tag, :p)
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 6b9b0a826b..3304605c1a 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -47,7 +47,7 @@ module ActionView
NAME_BLOCK = lambda {|cache, name| cache[name] = SmallCache.new(&PREFIX_BLOCK)}
KEY_BLOCK = lambda {|cache, key| cache[key] = SmallCache.new(&NAME_BLOCK)}
- # usually a majority of template look ups return nothing, use this canonical preallocated array to safe memory
+ # usually a majority of template look ups return nothing, use this canonical preallocated array to save memory
NO_TEMPLATES = [].freeze
def initialize
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index 9aee47bd52..a1f3d081db 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -3,6 +3,8 @@
* Add `ActiveModel::Errors#full_messages_for`, to return all the error messages
for a given attribute.
+ Example:
+
class Person
include ActiveModel::Validations
@@ -19,26 +21,27 @@
* Added a method so that validations can be easily cleared on a model.
For example:
- class Person
- include ActiveModel::Validations
+ class Person
+ include ActiveModel::Validations
- validates_uniqueness_of :first_name
- validate :cannot_be_robot
+ validates_uniqueness_of :first_name
+ validate :cannot_be_robot
- def cannot_be_robot
- errors.add(:base, 'A person cannot be a robot') if person_is_robot
+ def cannot_be_robot
+ errors.add(:base, 'A person cannot be a robot') if person_is_robot
+ end
end
- end
Now, if someone runs `Person.clear_validators!`, then the following occurs:
- Person.validators # => []
- Person._validate_callbacks.empty? # => true
+ Person.validators # => []
+ Person._validate_callbacks.empty? # => true
*John Wang*
* `has_secure_password` does not fail the confirmation validation
when assigning empty String to `password` and `password_confirmation`.
+ Fixes #9535.
Example:
diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc
index a66225319d..a399fe9051 100644
--- a/activemodel/README.rdoc
+++ b/activemodel/README.rdoc
@@ -24,8 +24,8 @@ to integrate with Action Pack out of the box: <tt>ActiveModel::Model</tt>.
end
person = Person.new(name: 'bob', age: '18')
- person.name # => 'bob'
- person.age # => '18'
+ person.name # => 'bob'
+ person.age # => '18'
person.valid? # => true
It includes model name introspections, conversions, translations and
@@ -82,12 +82,12 @@ behavior out of the box:
end
person = Person.new
- person.name # => nil
- person.changed? # => false
+ person.name # => nil
+ person.changed? # => false
person.name = 'bob'
- person.changed? # => true
- person.changed # => ['name']
- person.changes # => { 'name' => [nil, 'bob'] }
+ person.changed? # => true
+ person.changed # => ['name']
+ person.changes # => { 'name' => [nil, 'bob'] }
person.name = 'robert'
person.save
person.previous_changes # => {'name' => ['bob, 'robert']}
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index cf697d8b16..52300fd53f 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,16 +1,20 @@
## Rails 4.0.0 (unreleased) ##
+* `0x` prefix must be added when assigning hexadecimal string into `bit` column in PostgreSQL.
+
+ *kennyj*
+
* Added Statement Cache to allow the caching of a single statement. The cache works by
- duping the relation returned from yielding a statement which allows skipping the AST
- building phase.
+ duping the relation returned from yielding a statement, which allows skipping the AST
+ building phase for following executes. The cache returns results in array format.
Example:
- cache = ActiveRecord::StatementCache.new do
- Book.where(:name => "my book").limit(100)
- end
+ cache = ActiveRecord::StatementCache.new do
+ Book.where(name: "my book").limit(100)
+ end
- books = cache.execute
+ books = cache.execute
The solution attempts to get closer to the speed of `find_by_sql` but still maintaining
the expressiveness of the Active Record queries.
@@ -41,10 +45,9 @@
relation all the context that `Post` was joined with `Author` is lost and hence the error
that `author` was not found on `Comment`.
- Ths solution is to build JoinAssociation when two relations with join information are being
- merged. And later while building the arel use the previously built `JoinAssociation` record
+ The solution is to build `JoinAssociation` when two relations with join information are being
+ merged. And later while building the Arel use the previously built `JoinAssociation` record
in `JoinDependency#graft` to build the right from clause.
-
Fixes #3002.
*Jared Armstrong and Neeraj Singh*
@@ -76,7 +79,8 @@
*Michal Cichra*
* `has_many` using `:through` now obeys the order clause mentioned in
- through association. Fixes #10016.
+ through association.
+ Fixes #10016.
*Neeraj Singh*
@@ -106,8 +110,8 @@
*kennyj*
* Allow `ActiveRecord::Base.connection_handler` to have thread affinity and be
- settable, this effectively allows Active Record to be used in a multi threaded
- setup with multiple connections to multiple dbs.
+ settable, this effectively allows Active Record to be used in a multithreaded
+ setup with multiple connections to multiple databases.
*Sam Saffron*
@@ -141,7 +145,8 @@
*Ken Mazaika*
* Add an `add_index` override in PostgreSQL adapter and MySQL adapter
- to allow custom index type support. Fixes #6101.
+ to allow custom index type support.
+ Fixes #6101.
add_index(:wikis, :body, :using => 'gin')
@@ -165,7 +170,6 @@
in the association for a particular id. Then, it will go to the DB if it
is not found. This is accomplished by calling `find_by_scan` in
collection associations whenever `options[:inverse_of]` is not nil.
-
Fixes #9470.
*John Wang*
@@ -1275,7 +1279,7 @@
* Explain only normal CRUD sql (select / update / insert / delete).
Fix problem that explains unexplainable sql.
- Closes #7544 #6458.
+ Fixes #7544 #6458.
*kennyj*
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 3c92e379f1..5e5995f566 100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1073,6 +1073,9 @@ module ActiveRecord
# with +attributes+, linked to this object through a foreign key, and that has already
# been saved (if it passed the validation). *Note*: This only works if the base model
# already exists in the DB, not if it is a new (unsaved) record!
+ # [collection.create!(attributes = {})]
+ # Does the same as <tt>collection.create</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
+ # if the record is invalid.
#
# (*Note*: +collection+ is replaced with the symbol passed as the first argument, so
# <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.)
@@ -1094,6 +1097,7 @@ module ActiveRecord
# * <tt>Firm#clients.exists?(name: 'ACME')</tt> (similar to <tt>Client.exists?(name: 'ACME', firm_id: firm.id)</tt>)
# * <tt>Firm#clients.build</tt> (similar to <tt>Client.new("firm_id" => id)</tt>)
# * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save; c</tt>)
+ # * <tt>Firm#clients.create!</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save!</tt>)
# The declaration can also include an options hash to specialize the behavior of the association.
#
# === Options
diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb
index 729ef8c55a..db0553ea76 100644
--- a/activerecord/lib/active_record/associations/association.rb
+++ b/activerecord/lib/active_record/associations/association.rb
@@ -30,7 +30,7 @@ module ActiveRecord
reset_scope
end
- # Returns the name of the table of the related class:
+ # Returns the name of the table of the associated class:
#
# post.comments.aliased_table_name # => "comments"
#
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 8a5b312862..56e57cc36e 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -92,7 +92,7 @@ module ActiveRecord
# # => ActiveModel::MissingAttributeError: missing attribute: person_id
#
# *Second:* You can pass a block so it can be used just like Array#select.
- # This build an array of objects from the database for the scope,
+ # This builds an array of objects from the database for the scope,
# converting them into an array and iterating through them using
# Array#select.
#
@@ -304,7 +304,7 @@ module ActiveRecord
@association.concat(*records)
end
- # Replace this collection with +other_array+. This will perform a diff
+ # Replaces this collection with +other_array+. This will perform a diff
# and delete/add only records that have changed.
#
# class Person < ActiveRecord::Base
diff --git a/activerecord/lib/active_record/associations/join_dependency/join_part.rb b/activerecord/lib/active_record/associations/join_dependency/join_part.rb
index 9e33ccb59f..b534569063 100644
--- a/activerecord/lib/active_record/associations/join_dependency/join_part.rb
+++ b/activerecord/lib/active_record/associations/join_dependency/join_part.rb
@@ -1,7 +1,7 @@
module ActiveRecord
module Associations
class JoinDependency # :nodoc:
- # A JoinPart represents a part of a JoinDependency. It is an abstract class, inherited
+ # A JoinPart represents a part of a JoinDependency. It is inherited
# by JoinBase and JoinAssociation. A JoinBase represents the Active Record which
# everything else is being joined onto. A JoinAssociation represents an association which
# is joining to the base. A JoinAssociation may result in more than one actual join
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb
index 25d62fdb85..7f1ebab4cd 100644
--- a/activerecord/lib/active_record/attribute_methods/serialization.rb
+++ b/activerecord/lib/active_record/attribute_methods/serialization.rb
@@ -11,6 +11,12 @@ module ActiveRecord
end
module ClassMethods
+ ##
+ # :method: serialized_attributes
+ #
+ # Returns a hash of all the attributes that have been specified for
+ # serialization as keys and their class restriction as values.
+
# If you have an attribute that needs to be saved to the database as an
# object, and retrieved as the same object, then specify the name of that
# attribute using this method and it will be handled automatically. The
@@ -44,6 +50,7 @@ module ActiveRecord
end
end
+ # *DEPRECATED*: Use ActiveRecord::AttributeMethods::Serialization::ClassMethods#serialized_attributes class level method instead.
def serialized_attributes
message = "Instance level serialized_attributes method is deprecated, please use class level method."
ActiveSupport::Deprecation.warn message
@@ -86,10 +93,10 @@ module ActiveRecord
# This is only added to the model when serialize is called, which
# ensures we do not make things slower when serialization is not used.
- module Behavior #:nodoc:
+ module Behavior # :nodoc:
extend ActiveSupport::Concern
- module ClassMethods
+ module ClassMethods # :nodoc:
def initialize_attributes(attributes, options = {})
serialized = (options.delete(:serialized) { true }) ? :serialized : :unserialized
super(attributes, options)
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb
index 14ef07a75e..a9ef11aa83 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb
@@ -26,6 +26,15 @@ module ActiveRecord
end
end
+ def string_to_bit(value)
+ case value
+ when /^0x/i
+ value[2..-1].hex.to_s(2) # Hexadecimal notation
+ else
+ value # Bit-string notation
+ end
+ end
+
def hstore_to_string(object)
if Hash === object
object.map { |k,v|
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
index 51f377dfd7..1be116ce10 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -18,8 +18,19 @@ module ActiveRecord
end
end
+ class Bit < Type
+ def type_cast(value)
+ if String === value
+ ConnectionAdapters::PostgreSQLColumn.string_to_bit value
+ else
+ value
+ end
+ end
+ end
+
class Bytea < Type
def type_cast(value)
+ return if value.nil?
PGconn.unescape_bytea value
end
end
@@ -322,14 +333,14 @@ module ActiveRecord
# FIXME: why are we keeping these types as strings?
alias_type 'tsvector', 'text'
alias_type 'interval', 'text'
- alias_type 'bit', 'text'
- alias_type 'varbit', 'text'
alias_type 'macaddr', 'text'
alias_type 'uuid', 'text'
register_type 'money', OID::Money.new
register_type 'bytea', OID::Bytea.new
register_type 'bool', OID::Boolean.new
+ register_type 'bit', OID::Bit.new
+ register_type 'varbit', OID::Bit.new
register_type 'float4', OID::Float.new
alias_type 'float8', 'float4'
diff --git a/activerecord/lib/active_record/connection_handling.rb b/activerecord/lib/active_record/connection_handling.rb
index 3f175988db..a1943dfcb0 100644
--- a/activerecord/lib/active_record/connection_handling.rb
+++ b/activerecord/lib/active_record/connection_handling.rb
@@ -54,11 +54,11 @@ module ActiveRecord
end
def connection_id
- ActiveRecord::RuntimeRegistry.instance.connection_id
+ ActiveRecord::RuntimeRegistry.connection_id
end
def connection_id=(connection_id)
- ActiveRecord::RuntimeRegistry.instance.connection_id = connection_id
+ ActiveRecord::RuntimeRegistry.connection_id = connection_id
end
# Returns the configuration of the associated connection as a hash:
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index 7a8408155a..733d4e1c67 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -80,11 +80,11 @@ module ActiveRecord
class_attribute :default_connection_handler, instance_writer: false
def self.connection_handler
- ActiveRecord::RuntimeRegistry.instance.connection_handler || self.default_connection_handler
+ ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
end
def self.connection_handler=(handler)
- ActiveRecord::RuntimeRegistry.instance.connection_handler = handler
+ ActiveRecord::RuntimeRegistry.connection_handler = handler
end
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
diff --git a/activerecord/lib/active_record/explain.rb b/activerecord/lib/active_record/explain.rb
index 15736575a2..e65dab07ba 100644
--- a/activerecord/lib/active_record/explain.rb
+++ b/activerecord/lib/active_record/explain.rb
@@ -1,22 +1,22 @@
require 'active_support/lazy_load_hooks'
+require 'active_record/explain_registry'
module ActiveRecord
module Explain
- # Relation#explain needs to be able to collect the queries.
+ # Executes the block with the collect flag enabled. Queries are collected
+ # asynchronously by the subscriber and returned.
def collecting_queries_for_explain # :nodoc:
- current = Thread.current
- original, current[:available_queries_for_explain] = current[:available_queries_for_explain], []
+ ExplainRegistry.collect = true
yield
- return current[:available_queries_for_explain]
+ ExplainRegistry.queries
ensure
- # Note that the return value above does not depend on this assignment.
- current[:available_queries_for_explain] = original
+ ExplainRegistry.reset
end
# Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
# Returns a formatted string ready to be logged.
def exec_explain(queries) # :nodoc:
- str = queries && queries.map do |sql, bind|
+ str = queries.map do |sql, bind|
[].tap do |msg|
msg << "EXPLAIN for: #{sql}"
unless bind.empty?
@@ -31,6 +31,7 @@ module ActiveRecord
def str.inspect
self
end
+
str
end
end
diff --git a/activerecord/lib/active_record/explain_registry.rb b/activerecord/lib/active_record/explain_registry.rb
new file mode 100644
index 0000000000..b84a692b87
--- /dev/null
+++ b/activerecord/lib/active_record/explain_registry.rb
@@ -0,0 +1,30 @@
+require 'active_support/per_thread_registry'
+
+module ActiveRecord
+ # This is a thread locals registry for EXPLAIN. For example
+ #
+ # ActiveRecord::ExplainRegistry.queries
+ #
+ # returns the collected queries local to the current thread.
+ #
+ # See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
+ # for further details.
+ class ExplainRegistry
+ extend ActiveSupport::PerThreadRegistry
+
+ attr_accessor :queries, :collect
+
+ def initialize
+ reset
+ end
+
+ def collect?
+ @collect
+ end
+
+ def reset
+ @collect = false
+ @queries = []
+ end
+ end
+end \ No newline at end of file
diff --git a/activerecord/lib/active_record/explain_subscriber.rb b/activerecord/lib/active_record/explain_subscriber.rb
index 0f927496fb..a3bc56d600 100644
--- a/activerecord/lib/active_record/explain_subscriber.rb
+++ b/activerecord/lib/active_record/explain_subscriber.rb
@@ -1,4 +1,5 @@
require 'active_support/notifications'
+require 'active_record/explain_registry'
module ActiveRecord
class ExplainSubscriber # :nodoc:
@@ -7,8 +8,8 @@ module ActiveRecord
end
def finish(name, id, payload)
- if queries = Thread.current[:available_queries_for_explain]
- queries << payload.values_at(:sql, :binds) unless ignore_payload?(payload)
+ if ExplainRegistry.collect? && !ignore_payload?(payload)
+ ExplainRegistry.queries << payload.values_at(:sql, :binds)
end
end
diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb
index 69371a1dab..61e5c120df 100644
--- a/activerecord/lib/active_record/log_subscriber.rb
+++ b/activerecord/lib/active_record/log_subscriber.rb
@@ -3,11 +3,11 @@ module ActiveRecord
IGNORE_PAYLOAD_NAMES = ["SCHEMA", "EXPLAIN"]
def self.runtime=(value)
- ActiveRecord::RuntimeRegistry.instance.sql_runtime = value
+ ActiveRecord::RuntimeRegistry.sql_runtime = value
end
def self.runtime
- ActiveRecord::RuntimeRegistry.instance.sql_runtime ||= 0
+ ActiveRecord::RuntimeRegistry.sql_runtime ||= 0
end
def self.reset_runtime
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index d3edcf3cdb..451104106c 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -466,7 +466,7 @@ module ActiveRecord
@connection.respond_to?(:reverting) && @connection.reverting
end
- class ReversibleBlockHelper < Struct.new(:reverting)
+ class ReversibleBlockHelper < Struct.new(:reverting) # :nodoc:
def up
yield unless reverting
end
diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake
index 48febcbc43..2f35b2fbf6 100644
--- a/activerecord/lib/active_record/railties/databases.rake
+++ b/activerecord/lib/active_record/railties/databases.rake
@@ -383,5 +383,5 @@ namespace :railties do
end
end
-task 'test:prepare' => ['db:test:prepare', 'db:test:load_schema', 'db:abort_if_pending_migrations']
+task 'test:prepare' => ['db:test:prepare', 'db:test:load', 'db:abort_if_pending_migrations']
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 9403273db0..60eda96f08 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -75,8 +75,13 @@ module ActiveRecord
end
end
- # Abstract base class for AggregateReflection and AssociationReflection. Objects of
+ # Base class for AggregateReflection and AssociationReflection. Objects of
# AggregateReflection and AssociationReflection are returned by the Reflection::ClassMethods.
+ #
+ # MacroReflection
+ # AggregateReflection
+ # AssociationReflection
+ # ThroughReflection
class MacroReflection
# Returns the name of the macro.
#
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 06a220216a..6ee3711052 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -34,7 +34,6 @@ module ActiveRecord
#
# User.where.not(name: "Jon", role: "admin")
# # SELECT * FROM users WHERE name != 'Jon' AND role != 'admin'
- #
def not(opts, *rest)
where_value = @scope.send(:build_where, opts, rest).map do |rel|
case rel
@@ -353,7 +352,7 @@ module ActiveRecord
spawn.unscope!(*args)
end
- def unscope!(*args)
+ def unscope!(*args) # :nodoc:
args.flatten!
args.each do |scope|
diff --git a/activerecord/lib/active_record/runtime_registry.rb b/activerecord/lib/active_record/runtime_registry.rb
index 3f0ac68143..17890dd29f 100644
--- a/activerecord/lib/active_record/runtime_registry.rb
+++ b/activerecord/lib/active_record/runtime_registry.rb
@@ -1,29 +1,14 @@
require 'active_support/per_thread_registry'
module ActiveRecord
- # This is a registry class for storing local variables in active record. The
- # class allows you to access variables that are local to the current thread.
- # These thread local variables are stored as attributes in the
- # +RuntimeRegistry+ class.
- #
- # You can access the thread local variables by calling a variable's name on
- # the +RuntimeRegistry+ class. For example, if you wanted to obtain the
- # connection handler for the current thread, you would invoke:
- #
- # ActiveRecord::RuntimeRegistry.instance.connection_handler
- #
- # The +PerThreadRegistry+ module will make a new +RuntimeRegistry+ instance
- # and store it in +Thread.current+. Whenever you make a call for an attribute
- # on the +RuntimeRegistry+ class, the call will be sent to the instance that
- # is stored in +Thread.current+.
- #
- # Note that you can also make the following call which would provide an
- # equivalent result as the previous code:
+ # This is a thread locals registry for Active Record. For example
#
# ActiveRecord::RuntimeRegistry.connection_handler
#
- # However, this is less performant because it makes a call to +method_missing+
- # before it sends the method call to the +instance+.
+ # returns the connection handler local to the current thread.
+ #
+ # See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
+ # for further details.
class RuntimeRegistry
extend ActiveSupport::PerThreadRegistry
diff --git a/activerecord/lib/active_record/scoping.rb b/activerecord/lib/active_record/scoping.rb
index 6ab36a23a7..0cf3d59985 100644
--- a/activerecord/lib/active_record/scoping.rb
+++ b/activerecord/lib/active_record/scoping.rb
@@ -36,7 +36,7 @@ module ActiveRecord
# to get the current_scope for the +Board+ model, then you would use the
# following code:
#
- # registry = ActiveRecord::Scoping::ScopeRegistry.instance
+ # registry = ActiveRecord::Scoping::ScopeRegistry
# registry.set_value_for(:current_scope, "Board", some_new_scope)
#
# Now when you run:
@@ -52,10 +52,6 @@ module ActiveRecord
class ScopeRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry
- class << self
- delegate :value_for, :set_value_for, to: :instance
- end
-
VALID_SCOPE_TYPES = [:current_scope, :ignore_default_scope]
def initialize
diff --git a/activerecord/lib/active_record/statement_cache.rb b/activerecord/lib/active_record/statement_cache.rb
index 4a8c54414d..dd4ee0c4a0 100644
--- a/activerecord/lib/active_record/statement_cache.rb
+++ b/activerecord/lib/active_record/statement_cache.rb
@@ -3,15 +3,15 @@ module ActiveRecord
# Statement cache is used to cache a single statement in order to avoid creating the AST again.
# Initializing the cache is done by passing the statement in the initialization block:
#
- # cache = ActiveRecord::StatementCache.new do
- # Book.where(:name => "my book").limit(100)
- # end
+ # cache = ActiveRecord::StatementCache.new do
+ # Book.where(name: "my book").limit(100)
+ # end
#
# The cached statement is executed by using the +execute+ method:
#
- # cache.execute
+ # cache.execute
#
- # The relation returned by yield is cached, and for each +execute+ call the cached relation gets duped.
+ # The relation returned by the block is cached, and for each +execute+ call the cached relation gets duped.
# Database is queried when +to_a+ is called on the relation.
class StatementCache
def initialize
diff --git a/activerecord/test/cases/adapters/postgresql/bytea_test.rb b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
new file mode 100644
index 0000000000..d7d77f96e2
--- /dev/null
+++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
@@ -0,0 +1,87 @@
+# encoding: utf-8
+
+require "cases/helper"
+require 'active_record/base'
+require 'active_record/connection_adapters/postgresql_adapter'
+
+class PostgresqlByteaTest < ActiveRecord::TestCase
+ class ByteaDataType < ActiveRecord::Base
+ self.table_name = 'bytea_data_type'
+ end
+
+ def setup
+ @connection = ActiveRecord::Base.connection
+ begin
+ @connection.transaction do
+ @connection.create_table('bytea_data_type') do |t|
+ t.binary 'payload'
+ end
+ end
+ end
+ @column = ByteaDataType.columns.find { |c| c.name == 'payload' }
+ assert(@column.is_a?(ActiveRecord::ConnectionAdapters::PostgreSQLColumn))
+ end
+
+ def teardown
+ @connection.execute 'drop table if exists bytea_data_type'
+ end
+
+ def test_column
+ assert_equal :binary, @column.type
+ end
+
+ def test_type_cast_binary_converts_the_encoding
+ assert @column
+
+ data = "\u001F\x8B"
+ assert_equal('UTF-8', data.encoding.name)
+ assert_equal('ASCII-8BIT', @column.type_cast(data).encoding.name)
+ end
+
+ def test_type_cast_binary_value
+ data = "\u001F\x8B".force_encoding("BINARY")
+ assert_equal(data, @column.type_cast(data))
+ end
+
+ def test_type_case_nil
+ assert_equal(nil, @column.type_cast(nil))
+ end
+
+ def test_read_value
+ data = "\u001F"
+ @connection.execute "insert into bytea_data_type (payload) VALUES ('#{data}')"
+ record = ByteaDataType.first
+ assert_equal(data, record.payload)
+ record.delete
+ end
+
+ def test_read_nil_value
+ @connection.execute "insert into bytea_data_type (payload) VALUES (null)"
+ record = ByteaDataType.first
+ assert_equal(nil, record.payload)
+ record.delete
+ end
+
+ def test_write_value
+ data = "\u001F"
+ record = ByteaDataType.create(payload: data)
+ refute record.new_record?
+ assert_equal(data, record.payload)
+ end
+
+ def test_write_binary
+ data = File.read(File.join(File.dirname(__FILE__), '..', '..', '..', 'assets', 'example.log'))
+ assert(data.size > 1)
+ record = ByteaDataType.create(payload: data)
+ refute record.new_record?
+ assert_equal(data, record.payload)
+ assert_equal(data, ByteaDataType.where(id: record.id).first.payload)
+ end
+
+ def test_write_nil
+ record = ByteaDataType.create(payload: nil)
+ refute record.new_record?
+ assert_equal(nil, record.payload)
+ assert_equal(nil, ByteaDataType.where(id: record.id).first.payload)
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
index 1e6ae85a25..8c17372286 100644
--- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
@@ -545,13 +545,19 @@ _SQL
def test_update_bit_string
new_bit_string = '11111111'
- new_bit_string_varying = '11111110'
+ new_bit_string_varying = '0xFF'
assert @first_bit_string.bit_string = new_bit_string
assert @first_bit_string.bit_string_varying = new_bit_string_varying
assert @first_bit_string.save
assert @first_bit_string.reload
- assert_equal new_bit_string, @first_bit_string.bit_string
- assert_equal new_bit_string_varying, @first_bit_string.bit_string_varying
+ assert_equal @first_bit_string.bit_string, new_bit_string
+ assert_equal @first_bit_string.bit_string, @first_bit_string.bit_string_varying
+ end
+
+ def test_invalid_hex_string
+ new_bit_string = 'FF'
+ @first_bit_string.bit_string = new_bit_string
+ assert_raise(ActiveRecord::StatementInvalid) { assert @first_bit_string.save }
end
def test_update_oid
diff --git a/activerecord/test/cases/adapters/postgresql/explain_test.rb b/activerecord/test/cases/adapters/postgresql/explain_test.rb
index 619d581d5f..0b61f61572 100644
--- a/activerecord/test/cases/adapters/postgresql/explain_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/explain_test.rb
@@ -22,13 +22,6 @@ module ActiveRecord
assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" IN (1)), explain
assert_match %(Seq Scan on audit_logs), explain
end
-
- def test_dont_explain_for_set_search_path
- queries = Thread.current[:available_queries_for_explain] = []
- ActiveRecord::Base.connection.schema_search_path = "public"
- assert queries.empty?
- end
-
end
end
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 83fc0b48f9..bd568af06a 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1377,9 +1377,9 @@ class BasicsTest < ActiveRecord::TestCase
UnloadablePost.send(:current_scope=, UnloadablePost.all)
UnloadablePost.unloadable
- assert_not_nil ActiveRecord::Scoping::ScopeRegistry.instance.value_for(:current_scope, "UnloadablePost")
+ assert_not_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, "UnloadablePost")
ActiveSupport::Dependencies.remove_unloadable_constants!
- assert_nil ActiveRecord::Scoping::ScopeRegistry.instance.value_for(:current_scope, "UnloadablePost")
+ assert_nil ActiveRecord::Scoping::ScopeRegistry.value_for(:current_scope, "UnloadablePost")
ensure
Object.class_eval{ remove_const :UnloadablePost } if defined?(UnloadablePost)
end
diff --git a/activerecord/test/cases/explain_subscriber_test.rb b/activerecord/test/cases/explain_subscriber_test.rb
index b425967678..fb53a92c89 100644
--- a/activerecord/test/cases/explain_subscriber_test.rb
+++ b/activerecord/test/cases/explain_subscriber_test.rb
@@ -1,55 +1,54 @@
require 'cases/helper'
+require 'active_record/explain_subscriber'
+require 'active_record/explain_registry'
if ActiveRecord::Base.connection.supports_explain?
class ExplainSubscriberTest < ActiveRecord::TestCase
SUBSCRIBER = ActiveRecord::ExplainSubscriber.new
- def test_collects_nothing_if_available_queries_for_explain_is_nil
- with_queries(nil) do
- SUBSCRIBER.finish(nil, nil, {})
- assert_nil Thread.current[:available_queries_for_explain]
- end
+ def setup
+ ActiveRecord::ExplainRegistry.reset
+ ActiveRecord::ExplainRegistry.collect = true
end
def test_collects_nothing_if_the_payload_has_an_exception
- with_queries([]) do |queries|
- SUBSCRIBER.finish(nil, nil, :exception => Exception.new)
- assert queries.empty?
- end
+ SUBSCRIBER.finish(nil, nil, exception: Exception.new)
+ assert queries.empty?
end
def test_collects_nothing_for_ignored_payloads
- with_queries([]) do |queries|
- ActiveRecord::ExplainSubscriber::IGNORED_PAYLOADS.each do |ip|
- SUBSCRIBER.finish(nil, nil, :name => ip)
- end
- assert queries.empty?
+ ActiveRecord::ExplainSubscriber::IGNORED_PAYLOADS.each do |ip|
+ SUBSCRIBER.finish(nil, nil, name: ip)
end
+ assert queries.empty?
+ end
+
+ def test_collects_nothing_if_collect_is_false
+ ActiveRecord::ExplainRegistry.collect = false
+ SUBSCRIBER.finish(nil, nil, name: 'SQL', sql: 'select 1 from users', binds: [1, 2])
+ assert queries.empty?
end
def test_collects_pairs_of_queries_and_binds
sql = 'select 1 from users'
binds = [1, 2]
- with_queries([]) do |queries|
- SUBSCRIBER.finish(nil, nil, :name => 'SQL', :sql => sql, :binds => binds)
- assert_equal 1, queries.size
- assert_equal sql, queries[0][0]
- assert_equal binds, queries[0][1]
- end
+ SUBSCRIBER.finish(nil, nil, name: 'SQL', sql: sql, binds: binds)
+ assert_equal 1, queries.size
+ assert_equal sql, queries[0][0]
+ assert_equal binds, queries[0][1]
end
- def test_collects_nothing_if_unexplained_sqls
- with_queries([]) do |queries|
- SUBSCRIBER.finish(nil, nil, :name => 'SQL', :sql => 'SHOW max_identifier_length')
- assert queries.empty?
- end
+ def test_collects_nothing_if_the_statement_is_not_whitelisted
+ SUBSCRIBER.finish(nil, nil, name: 'SQL', sql: 'SHOW max_identifier_length')
+ assert queries.empty?
+ end
+
+ def teardown
+ ActiveRecord::ExplainRegistry.reset
end
- def with_queries(queries)
- Thread.current[:available_queries_for_explain] = queries
- yield queries
- ensure
- Thread.current[:available_queries_for_explain] = nil
+ def queries
+ ActiveRecord::ExplainRegistry.queries
end
end
end
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb
index 1967d8716a..34ecdb3cc9 100644
--- a/activerecord/test/cases/relation_test.rb
+++ b/activerecord/test/cases/relation_test.rb
@@ -182,7 +182,7 @@ module ActiveRecord
def test_relation_merging_with_merged_joins
special_comments_with_ratings = SpecialComment.joins(:ratings)
posts_with_special_comments_with_ratings = Post.group("posts.id").joins(:special_comments).merge(special_comments_with_ratings)
- assert_equal 3, authors(:david).posts.merge(posts_with_special_comments_with_ratings).to_a.length
+ assert_equal 3, authors(:david).posts.merge(posts_with_special_comments_with_ratings).count.length
end
end
diff --git a/activerecord/test/cases/statement_cache_test.rb b/activerecord/test/cases/statement_cache_test.rb
index a8c97cccd4..76da49707f 100644
--- a/activerecord/test/cases/statement_cache_test.rb
+++ b/activerecord/test/cases/statement_cache_test.rb
@@ -23,7 +23,7 @@ module ActiveRecord
def test_statement_cache_with_nil_statement_raises_error
assert_raise(ArgumentError) do
- cache = ActiveRecord::StatementCache.new do
+ ActiveRecord::StatementCache.new do
nil
end
end
@@ -36,7 +36,7 @@ module ActiveRecord
salty = Liquid.create(name: 'salty')
molecule = salty.molecules.create(name: 'dioxane')
- electron = molecule.electrons.create(name: 'lepton')
+ molecule.electrons.create(name: 'lepton')
liquids = cache.execute
assert_equal "salty", liquids[0].name
@@ -47,13 +47,13 @@ module ActiveRecord
Book.where(name: "my book")
end
- for i in 0..2 do
+ 3.times do
Book.create(name: "my book")
end
first_books = cache.execute
- for i in 0..2 do
+ 3.times do
Book.create(name: "my book")
end
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index a4c6ea4236..84a03825dc 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,5 +1,11 @@
## Rails 4.0.0 (unreleased) ##
+* An `ActiveSupport::Subscriber` class has been extracted from
+ `ActiveSupport::LogSubscriber`, allowing you to use the event attachment
+ API for other kinds of subscribers.
+
+ *Daniel Schierbeck*
+
* `Class#class_attribute` accepts an `instance_predicate` option which
defaults to `true`. If set to `false` the predicate method will not
be defined.
@@ -8,8 +14,8 @@
* `fast_xs` support has been removed. Use `String#encode(xml: :attr)`.
-* `ActiveSupport::Notifications::Instrumenter#instrument` should yield
- its payload.
+* `ActiveSupport::Notifications::Instrumenter#instrument` should
+ yield its payload.
*stopdropandrew*
@@ -93,7 +99,7 @@
* Improve `String#squish` to handle Unicode whitespace. *Antoine Lyset*
-* Standardize on `to_time` returning an instance of `Time` in the local system timezone
+* Standardise on `to_time` returning an instance of `Time` in the local system timezone
across `String`, `Time`, `Date`, `DateTime` and `ActiveSupport::TimeWithZone`.
*Andrew White*
@@ -159,7 +165,7 @@
* Remove surrogate unicode character encoding from `ActiveSupport::JSON.encode`
The encoding scheme was broken for unicode characters outside the basic multilingual plane;
- since JSON is assumed to be UTF-8, and we already force the encoding to UTF-8,
+ since json is assumed to be UTF-8, and we already force the encoding to UTF-8,
simply pass through the un-encoded characters.
*Brett Carter*
@@ -378,7 +384,7 @@
* An optional block can be passed to `HashWithIndifferentAccess#update` and `#merge`.
The block will be invoked for each duplicated key, and used to resolve the conflict,
- thus replicating the behavior of the corresponding methods on the `Hash` class.
+ thus replicating the behaviour of the corresponding methods on the `Hash` class.
*Leo Cassarani*
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index 430a35fbaf..3807ee63b1 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -12,7 +12,7 @@ class Array
# pass an option key that doesn't exist in the list below, it will raise an
# <tt>ArgumentError</tt>.
#
- # Options:
+ # ==== Options
#
# * <tt>:words_connector</tt> - The sign or word used to join the elements
# in arrays with two or more elements (default: ", ").
@@ -24,6 +24,8 @@ class Array
# the connector options defined on the 'support.array' namespace in the
# corresponding dictionary file.
#
+ # ==== Examples
+ #
# [].to_sentence # => ""
# ['one'].to_sentence # => "one"
# ['one', 'two'].to_sentence # => "one and two"
@@ -38,10 +40,10 @@ class Array
# ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
# # => "one or two or at least three"
#
- # Examples using <tt>:locale</tt> option:
+ # Using <tt>:locale</tt> option:
#
# # Given this locale dictionary:
- # #
+ # #
# # es:
# # support:
# # array:
diff --git a/activesupport/lib/active_support/core_ext/array/uniq_by.rb b/activesupport/lib/active_support/core_ext/array/uniq_by.rb
index ca3b7748cd..23573c97de 100644
--- a/activesupport/lib/active_support/core_ext/array/uniq_by.rb
+++ b/activesupport/lib/active_support/core_ext/array/uniq_by.rb
@@ -1,5 +1,5 @@
class Array
- # *DEPRECATED*: Use +Array#uniq+ instead.
+ # *DEPRECATED*: Use <tt>Array#uniq</tt> instead.
#
# Returns a unique array based on the criteria in the block.
#
@@ -9,7 +9,7 @@ class Array
uniq(&block)
end
- # *DEPRECATED*: Use +Array#uniq!+ instead.
+ # *DEPRECATED*: Use <tt>Array#uniq!</tt> instead.
#
# Same as +uniq_by+, but modifies +self+.
def uniq_by!(&block)
diff --git a/activesupport/lib/active_support/core_ext/benchmark.rb b/activesupport/lib/active_support/core_ext/benchmark.rb
index 2d110155a5..eb25b2bc44 100644
--- a/activesupport/lib/active_support/core_ext/benchmark.rb
+++ b/activesupport/lib/active_support/core_ext/benchmark.rb
@@ -1,6 +1,13 @@
require 'benchmark'
class << Benchmark
+ # Benchmark realtime in milliseconds.
+ #
+ # Benchmark.realtime { User.all }
+ # # => 8.0e-05
+ #
+ # Benchmark.ms { User.all }
+ # # => 0.074
def ms
1000 * realtime { yield }
end
diff --git a/activesupport/lib/active_support/core_ext/module/deprecation.rb b/activesupport/lib/active_support/core_ext/module/deprecation.rb
index cc45cee5b8..d873de197f 100644
--- a/activesupport/lib/active_support/core_ext/module/deprecation.rb
+++ b/activesupport/lib/active_support/core_ext/module/deprecation.rb
@@ -14,8 +14,8 @@ class Module
# method where you can implement your custom warning behavior.
#
# class MyLib::Deprecator
- # def deprecation_warning(deprecated_method_name, message, caller_backtrace)
- # message = "#{method_name} is deprecated and will be removed from MyLibrary | #{message}"
+ # def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil)
+ # message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}"
# Kernel.warn message
# end
# end
diff --git a/activesupport/lib/active_support/core_ext/string/filters.rb b/activesupport/lib/active_support/core_ext/string/filters.rb
index a1b3f79748..c62bb41416 100644
--- a/activesupport/lib/active_support/core_ext/string/filters.rb
+++ b/activesupport/lib/active_support/core_ext/string/filters.rb
@@ -50,6 +50,6 @@ class String
length_with_room_for_omission
end
- self[0...stop] + options[:omission]
+ "#{self[0...stop]}#{options[:omission]}"
end
end
diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb
index 6522145572..0b506a6030 100644
--- a/activesupport/lib/active_support/core_ext/string/inflections.rb
+++ b/activesupport/lib/active_support/core_ext/string/inflections.rb
@@ -41,7 +41,7 @@ class String
#
# If the optional parameter +locale+ is specified,
# the word will be singularized as a word of that language.
- # By default, this paramter is set to <tt>:en</tt>.
+ # By default, this parameter is set to <tt>:en</tt>.
# You must define your own inflection rules for languages other than English.
#
# 'posts'.singularize # => "post"
diff --git a/activesupport/lib/active_support/log_subscriber.rb b/activesupport/lib/active_support/log_subscriber.rb
index c4b64bd1a6..e95dc5a866 100644
--- a/activesupport/lib/active_support/log_subscriber.rb
+++ b/activesupport/lib/active_support/log_subscriber.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/class/attribute'
+require 'active_support/subscriber'
module ActiveSupport
# ActiveSupport::LogSubscriber is an object set to consume
@@ -33,7 +34,7 @@ module ActiveSupport
# Log subscriber also has some helpers to deal with logging and automatically
# flushes all logs when the request finishes (via action_dispatch.callback
# notification) in a Rails environment.
- class LogSubscriber
+ class LogSubscriber < Subscriber
# Embed in a String to clear all previous ANSI sequences.
CLEAR = "\e[0m"
BOLD = "\e[1m"
@@ -60,18 +61,8 @@ module ActiveSupport
attr_writer :logger
- def attach_to(namespace, log_subscriber=new, notifier=ActiveSupport::Notifications)
- log_subscribers << log_subscriber
-
- log_subscriber.public_methods(false).each do |event|
- next if %w{ start finish }.include?(event.to_s)
-
- notifier.subscribe("#{event}.#{namespace}", log_subscriber)
- end
- end
-
def log_subscribers
- @@log_subscribers ||= []
+ subscribers
end
# Flush all log_subscribers' logger.
@@ -80,39 +71,18 @@ module ActiveSupport
end
end
- def initialize
- @queue_key = [self.class.name, object_id].join "-"
- super
- end
-
def logger
LogSubscriber.logger
end
def start(name, id, payload)
- return unless logger
-
- e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
- parent = event_stack.last
- parent << e if parent
-
- event_stack.push e
+ super if logger
end
def finish(name, id, payload)
- return unless logger
-
- finished = Time.now
- event = event_stack.pop
- event.end = finished
- event.payload.merge!(payload)
-
- method = name.split('.').first
- begin
- send(method, event)
- rescue Exception => e
- logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
- end
+ super if logger
+ rescue Exception => e
+ logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
end
protected
@@ -135,11 +105,5 @@ module ActiveSupport
bold = bold ? BOLD : ""
"#{bold}#{color}#{text}#{CLEAR}"
end
-
- private
-
- def event_stack
- Thread.current[@queue_key] ||= []
- end
end
end
diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index 5c985601f4..c45358bba9 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -193,10 +193,6 @@ module ActiveSupport
class InstrumentationRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry
- class << self
- delegate :instrumenter_for, to: :instance
- end
-
def initialize
@registry = {}
end
diff --git a/activesupport/lib/active_support/per_thread_registry.rb b/activesupport/lib/active_support/per_thread_registry.rb
index fb9a4c0e33..aa682fb36c 100644
--- a/activesupport/lib/active_support/per_thread_registry.rb
+++ b/activesupport/lib/active_support/per_thread_registry.rb
@@ -1,41 +1,52 @@
module ActiveSupport
- # This module creates a local registry class inside each thread. It provides
- # basic methods which will store thread locals in a single class. This
- # prevents the proliferation of too many thread locals and allows you to
- # explicitly keep track of each of the variables you're using as thread
- # locals in a class which includes this module.
+ # This module is used to encapsulate access to thread local variables.
#
- # For example, instead of using a bunch of different thread locals to keep
- # track of some variables like so:
+ # Instead of polluting the thread locals namespace:
#
- # Thread.current[:active_record_connection_handler] = connection_handler
- # Thread.current[:active_record_sql_runtime] = sql_runtime
+ # Thread.current[:connection_handler]
#
- # You could use the following class which implements the +PerThreadRegistry+
- # module:
+ # you define a class that extends this module:
#
- # class NewRegistry
- # extend ActiveSupport::PerThreadRegistry
+ # module ActiveRecord
+ # class RuntimeRegistry
+ # extend ActiveSupport::PerThreadRegistry
#
- # attr_accessor :connection_handler, :sql_runtime
+ # attr_accessor :connection_handler
+ # end
# end
#
- # NewRegistry.instance.connection_handler = connection_handler
- # NewRegistry.instance.sql_runtime = sql_runtime
+ # and invoke the declared instance accessors as class methods. So
#
- # The new way of keeping track of the thread locals will create a new local
- # inside of +Thread.current+ with a key which is the name of the extended
- # class. Now you can easily access per thread variables by just calling the
- # variable name on the registry.
+ # ActiveRecord::RuntimeRegistry.connection_handler = connection_handler
+ #
+ # sets a connection handler local to the current thread, and
+ #
+ # ActiveRecord::RuntimeRegistry.connection_handler
+ #
+ # returns a connection handler local to the current thread.
+ #
+ # This feature is accomplished by instantiating the class and storing the
+ # instance as a thread local keyed by the class name. In the example above
+ # a key "ActiveRecord::RuntimeRegistry" is stored in <tt>Thread.current</tt>.
+ # The class methods proxy to said thread local instance.
+ #
+ # If the class has an initializer, it must accept no arguments.
module PerThreadRegistry
- def instance
- Thread.current[self.name] ||= new
- end
-
protected
- def method_missing(*args, &block)
- instance.public_send(*args, &block)
+ def method_missing(name, *args, &block) # :nodoc:
+ # Caches the method definition as a singleton method of the receiver.
+ define_singleton_method(name) do |*a, &b|
+ per_thread_registry_instance.public_send(name, *a, &b)
+ end
+
+ send(name, *args, &block)
+ end
+
+ private
+
+ def per_thread_registry_instance
+ Thread.current[name] ||= new
end
end
end
diff --git a/activesupport/lib/active_support/subscriber.rb b/activesupport/lib/active_support/subscriber.rb
new file mode 100644
index 0000000000..ab76cf5c85
--- /dev/null
+++ b/activesupport/lib/active_support/subscriber.rb
@@ -0,0 +1,75 @@
+module ActiveSupport
+ # ActiveSupport::Subscriber is an object set to consume
+ # ActiveSupport::Notifications. The subscriber dispatches notifications to
+ # a registered object based on its given namespace.
+ #
+ # An example would be Active Record subscriber responsible for collecting
+ # statistics about queries:
+ #
+ # module ActiveRecord
+ # class StatsSubscriber < ActiveSupport::Subscriber
+ # def sql(event)
+ # Statsd.timing("sql.#{event.payload[:name]}", event.duration)
+ # end
+ # end
+ # end
+ #
+ # And it's finally registered as:
+ #
+ # ActiveRecord::StatsSubscriber.attach_to :active_record
+ #
+ # Since we need to know all instance methods before attaching the log
+ # subscriber, the line above should be called after your subscriber definition.
+ #
+ # After configured, whenever a "sql.active_record" notification is published,
+ # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
+ # the +sql+ method.
+ class Subscriber
+ class << self
+
+ # Attach the subscriber to a namespace.
+ def attach_to(namespace, subscriber=new, notifier=ActiveSupport::Notifications)
+ subscribers << subscriber
+
+ subscriber.public_methods(false).each do |event|
+ next if %w{ start finish }.include?(event.to_s)
+
+ notifier.subscribe("#{event}.#{namespace}", subscriber)
+ end
+ end
+
+ def subscribers
+ @@subscribers ||= []
+ end
+ end
+
+ def initialize
+ @queue_key = [self.class.name, object_id].join "-"
+ super
+ end
+
+ def start(name, id, payload)
+ e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
+ parent = event_stack.last
+ parent << e if parent
+
+ event_stack.push e
+ end
+
+ def finish(name, id, payload)
+ finished = Time.now
+ event = event_stack.pop
+ event.end = finished
+ event.payload.merge!(payload)
+
+ method = name.split('.').first
+ send(method, event)
+ end
+
+ private
+
+ def event_stack
+ Thread.current[@queue_key] ||= []
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 21a0620c22..3cf82a24b9 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -5,7 +5,7 @@ module ActiveSupport
# The TimeZone class serves as a wrapper around TZInfo::Timezone instances.
# It allows us to do the following:
#
- # * Limit the set of zones provided by TZInfo to a meaningful subset of 142
+ # * Limit the set of zones provided by TZInfo to a meaningful subset of 146
# zones.
# * Retrieve and display zones with a friendlier name
# (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
@@ -177,6 +177,7 @@ module ActiveSupport
"Wellington" => "Pacific/Auckland",
"Nuku'alofa" => "Pacific/Tongatapu",
"Tokelau Is." => "Pacific/Fakaofo",
+ "Chatham Is." => "Pacific/Chatham",
"Samoa" => "Pacific/Apia"
}
diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb
index 6aea9d56f1..c3fe89de4b 100644
--- a/activesupport/test/ordered_hash_test.rb
+++ b/activesupport/test/ordered_hash_test.rb
@@ -244,11 +244,7 @@ class OrderedHashTest < ActiveSupport::TestCase
end
def test_each_after_yaml_serialization
- values = []
- @deserialized_ordered_hash = YAML.load(YAML.dump(@ordered_hash))
-
- @deserialized_ordered_hash.each {|key, value| values << value}
- assert_equal @values, values
+ assert_equal @values, YAML.load(YAML.dump(@ordered_hash)).values
end
def test_each_when_yielding_to_block_with_splat
diff --git a/guides/assets/images/getting_started/unknown_action_create_for_posts.png b/guides/assets/images/getting_started/unknown_action_create_for_posts.png
index c0de53555d..d60a30465f 100644
--- a/guides/assets/images/getting_started/unknown_action_create_for_posts.png
+++ b/guides/assets/images/getting_started/unknown_action_create_for_posts.png
Binary files differ
diff --git a/guides/rails_guides/markdown/renderer.rb b/guides/rails_guides/markdown/renderer.rb
index c3fe5b8799..2eb7ca17a3 100644
--- a/guides/rails_guides/markdown/renderer.rb
+++ b/guides/rails_guides/markdown/renderer.rb
@@ -65,7 +65,7 @@ HTML
# if a bulleted list follows the first item is not rendered
# as a list item, but as a paragraph starting with a plain
# asterisk.
- body.gsub(/^(TIP|IMPORTANT|CAUTION|WARNING|NOTE|INFO|TODO)[.:](.*?)(\n(?=\n)|\Z)/m) do |m|
+ body.gsub(/^(TIP|IMPORTANT|CAUTION|WARNING|NOTE|INFO|TODO)[.:](.*?)(\n(?=\n)|\Z)/m) do
css_class = case $1
when 'CAUTION', 'IMPORTANT'
'warning'
diff --git a/guides/source/4_0_release_notes.md b/guides/source/4_0_release_notes.md
index 37afb25181..2793d9025f 100644
--- a/guides/source/4_0_release_notes.md
+++ b/guides/source/4_0_release_notes.md
@@ -113,7 +113,7 @@ Please refer to the [Changelog](https://github.com/rails/rails/blob/master/activ
* Add `ActiveModel::ForbiddenAttributesProtection`, a simple module to protect attributes from mass assignment when non-permitted attributes are passed.
-* Added `ActiveModel::Model`, a mixin to make Ruby objects work with AP out of box.
+* Added `ActiveModel::Model`, a mixin to make Ruby objects work with ActionPack out of box.
### Deprecations
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index 5e99063da8..db91425c76 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -27,6 +27,16 @@ A controller can thus be thought of as a middle man between models and views. It
NOTE: For more details on the routing process, see [Rails Routing from the Outside In](routing.html).
+Controller Naming Convention
+----------------------------
+
+The naming convention of controllers in Rails favors pluralization of the last word in the controller's name, although it is not strictly required (e.g. `ApplicationController`). For example, `ClientsController` is preferable to `ClientController`, `SiteAdminsController` is preferable to `SiteAdminController` or `SitesAdminsController`, and so on.
+
+Following this convention will allow you to use the default route generators (e.g. `resources`, etc) without needing to qualify each `:path` or `:controller`, and keeps URL and path helpers' usage consistent throughout your application. See [Layouts & Rendering Guide](layouts_and_rendering.html) for more details.
+
+NOTE: The controller naming convention differs from the naming convention of models, which expected to be named in singular form.
+
+
Methods and Actions
-------------------
@@ -561,7 +571,7 @@ Note that while for session values you set the key to `nil`, to delete a cookie
Rendering xml and json data
---------------------------
-ActionController makes it extremely easy to render `xml` or `json` data. If you generate a controller using scaffolding then it would look something like this:
+ActionController makes it extremely easy to render `xml` or `json` data. If you've generated a controller using scaffolding, it would look something like this:
```ruby
class UsersController < ApplicationController
@@ -576,7 +586,7 @@ class UsersController < ApplicationController
end
```
-Notice that in the above case code is `render xml: @users` and not `render xml: @users.to_xml`. That is because if the input is not string then rails automatically invokes `to_xml` .
+You may notice in the above code that we're using `render xml: @users`, not `render xml: @users.to_xml`. If the object is not a String, then Rails will automatically invoke `to_xml` for us.
Filters
-------
@@ -599,15 +609,6 @@ class ApplicationController < ActionController::Base
redirect_to new_login_url # halts request cycle
end
end
-
- # The logged_in? method simply returns true if the user is logged
- # in and false otherwise. It does this by "booleanizing" the
- # current_user method we created previously using a double ! operator.
- # Note that this is not common in Ruby and is discouraged unless you
- # really mean to convert something into true or false.
- def logged_in?
- !!current_user
- end
end
```
@@ -788,7 +789,7 @@ Rails comes with two built-in HTTP authentication mechanisms:
HTTP basic authentication is an authentication scheme that is supported by the majority of browsers and other HTTP clients. As an example, consider an administration section which will only be available by entering a username and a password into the browser's HTTP basic dialog window. Using the built-in authentication is quite easy and only requires you to use one method, `http_basic_authenticate_with`.
```ruby
-class AdminController < ApplicationController
+class AdminsController < ApplicationController
http_basic_authenticate_with name: "humbaba", password: "5baa61e4"
end
```
@@ -800,7 +801,7 @@ With this in place, you can create namespaced controllers that inherit from `Adm
HTTP digest authentication is superior to the basic authentication as it does not require the client to send an unencrypted password over the network (though HTTP basic authentication is safe over HTTPS). Using digest authentication with Rails is quite easy and only requires using one method, `authenticate_or_request_with_http_digest`.
```ruby
-class AdminController < ApplicationController
+class AdminsController < ApplicationController
USERS = { "lifo" => "world" }
before_action :authenticate
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index 1e7ceebdca..ec7b8d4e17 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -17,10 +17,7 @@ After reading this guide, you will know:
Introduction
------------
-Action Mailer allows you to send emails from your application using a mailer
-model and views. So, in Rails, emails are used by creating mailers that inherit
-from `ActionMailer::Base` and live in `app/mailers`. Those mailers have
-associated views that appear alongside controller views in `app/views`.
+Action Mailer allows you to send emails from your application using mailer classes and views. Mailers work very similarly to controllers. They inherit from `ActionMailer::Base` and live in `app/mailers`, and they have associated views that appear in `app/views`.
Sending Emails
--------------
@@ -87,11 +84,8 @@ Here is a quick explanation of the items presented in the preceding method. For
a full list of all available options, please have a look further down at the
Complete List of Action Mailer user-settable attributes section.
-* `default Hash` - This is a hash of default values for any email you send, in
- this case we are setting the `:from` header to a value for all messages in
- this class, this can be overridden on a per email basis
-* `mail` - The actual email message, we are passing the `:to` and `:subject`
- headers in.
+* `default Hash` - This is a hash of default values for any email you send from this mailer. In this case we are setting the `:from` header to a value for all messages in this class. This can be overridden on a per-email basis.
+* `mail` - The actual email message, we are passing the `:to` and `:subject` headers in.
Just like controllers, any instance variables we define in the method become
available for use in the views.
@@ -149,7 +143,7 @@ controller tell the Mailer to send an email when a user is successfully created.
Setting this up is painfully simple.
-First off, we need to create a simple `User` scaffold:
+First, let's create a simple `User` scaffold:
```bash
$ rails generate scaffold user name email login
@@ -241,8 +235,9 @@ encoded and not try to Base64 encode it.
#### Making Inline Attachments
-* Firstly, to tell Mail to turn an attachment into an inline attachment, you
- just call `#inline` on the attachments method within your Mailer:
+Action Mailer 3.0 makes inline attachments, which involved a lot of hacking in pre 3.0 versions, much simpler and trivial as they should be.
+
+* First, to tell Mail to turn an attachment into an inline attachment, you just call `#inline` on the attachments method within your Mailer:
```ruby
def welcome
@@ -296,7 +291,7 @@ The same format can be used to set carbon copy (Cc:) and blind carbon copy
Sometimes you wish to show the name of the person instead of just their email
address when they receive the email. The trick to doing that is to format the
-email address in the format `"Name <email>"`.
+email address in the format `"Full Name <email>"`.
```ruby
def welcome_email(user)
@@ -366,7 +361,7 @@ needs to be the same as your mailer, such as `user_mailer.html.erb` and
`user_mailer.text.erb` to be automatically recognized by your mailer as a
layout.
-In order to use a different file just use:
+In order to use a different file, call `layout` in your mailer:
```ruby
class UserMailer < ActionMailer::Base
@@ -677,7 +672,7 @@ config.action_mailer.smtp_settings = {
Mailer Testing
--------------
-You can find detailed instructions on how to test your mailers in our
+You can find detailed instructions on how to test your mailers in the
[testing guide](testing.html#testing-your-mailers).
Intercepting Emails
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index 3b5963efc2..dea1ddef71 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -172,7 +172,7 @@ That code will pull in the partial from `app/views/shared/_menu.html.erb`.
#### 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:
+One way to use partials is to treat them as the equivalent of subroutines; 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 looks like this:
```html+erb
<%= render "shared/ad_banner" %>
@@ -269,12 +269,7 @@ Rails will render the `_product_ruler` partial (with no data passed to it) betwe
### Layouts
-TODO...
-
-Using Templates, Partials and Layouts "The Rails Way"
---------------------------------------------------------
-
-TODO...
+Layouts can be used to render a common view template around the results of Rails controller actions. Typically, every Rails has a couple of overall layouts that most pages are rendered within. For example, a site might have a layout for a logged in user, and a layout for the marketing or sales side of the site. The logged in user layout might include top-level navigation that should be present across many controller actions. The sales layout for a SaaS app might include top-level navigation for things like "Pricing" and "Contact Us." You would expect each layout to have a different look and feel. You can read more details about Layouts in the [Layouts and Rendering in Rails](layouts_and_rendering.html) guide.
Partial Layouts
---------------
diff --git a/guides/source/active_record_basics.md b/guides/source/active_record_basics.md
index 69d7333e6f..fc8fac4651 100644
--- a/guides/source/active_record_basics.md
+++ b/guides/source/active_record_basics.md
@@ -1,14 +1,14 @@
Active Record Basics
====================
-
+
This guide is an introduction to Active Record.
After reading this guide, you will know:
-* What Object Relational Mapping and Active Record are and how they are used in
+* What Object Relational Mapping and Active Record are and how they are used in
Rails.
* How Active Record fits into the Model-View-Controller paradigm.
-* How to use Active Record models to manipulate data stored in a relational
+* How to use Active Record models to manipulate data stored in a relational
database.
* Active Record schema naming conventions.
* The concepts of database migrations, validations and callbacks.
@@ -18,33 +18,34 @@ After reading this guide, you will know:
What is Active Record?
----------------------
-Active Record is the M in [MVC](getting_started.html#the-mvc-architecture) - the
-model - which is the layer of the system responsible for representing business
-data and logic. Active Record facilitates the creation and use of business
-objects whose data requires persistent storage to a database. It is an
-implementation of the Active Record pattern which itself is a description of an
+Active Record is the M in [MVC](getting_started.html#the-mvc-architecture) - the
+model - which is the layer of the system responsible for representing business
+data and logic. Active Record facilitates the creation and use of business
+objects whose data requires persistent storage to a database. It is an
+implementation of the Active Record pattern which itself is a description of an
Object Relational Mapping system.
### The Active Record Pattern
-Active Record was described by Martin Fowler in his book _Patterns of Enterprise
-Application Architecture_. In Active Record, objects carry both persistent data
-and behavior which operates on that data. Active Record takes the opinion that
-ensuring data access logic is part of the object will educate users of that
+[Active Record was described by Martin Fowler](http://www.martinfowler.com/eaaCatalog/activeRecord.html)
+in his book _Patterns of Enterprise Application Architecture_. In
+Active Record, objects carry both persistent data and behavior which
+operates on that data. Active Record takes the opinion that ensuring
+data access logic is part of the object will educate users of that
object on how to write to and read from the database.
### Object Relational Mapping
-Object-Relational Mapping, commonly referred to as its abbreviation ORM, is
-a technique that connects the rich objects of an application to tables in
-a relational database management system. Using ORM, the properties and
-relationships of the objects in an application can be easily stored and
-retrieved from a database without writing SQL statements directly and with less
+Object-Relational Mapping, commonly referred to as its abbreviation ORM, is
+a technique that connects the rich objects of an application to tables in
+a relational database management system. Using ORM, the properties and
+relationships of the objects in an application can be easily stored and
+retrieved from a database without writing SQL statements directly and with less
overall database access code.
### Active Record as an ORM Framework
-Active Record gives us several mechanisms, the most important being the ability
+Active Record gives us several mechanisms, the most important being the ability
to:
* Represent models and their data
@@ -56,29 +57,29 @@ to:
Convention over Configuration in Active Record
----------------------------------------------
-When writing applications using other programming languages or frameworks, it
-may be necessary to write a lot of configuration code. This is particularly true
-for ORM frameworks in general. However, if you follow the conventions adopted by
-Rails, you'll need to write very little configuration (in some case no
-configuration at all) when creating Active Record models. The idea is that if
-you configure your applications in the very same way most of the times then this
-should be the default way. In this cases, explicit configuration would be needed
+When writing applications using other programming languages or frameworks, it
+may be necessary to write a lot of configuration code. This is particularly true
+for ORM frameworks in general. However, if you follow the conventions adopted by
+Rails, you'll need to write very little configuration (in some case no
+configuration at all) when creating Active Record models. The idea is that if
+you configure your applications in the very same way most of the times then this
+should be the default way. In this cases, explicit configuration would be needed
only in those cases where you can't follow the conventions for any reason.
### Naming Conventions
-By default, Active Record uses some naming conventions to find out how the
-mapping between models and database tables should be created. Rails will
-pluralize your class names to find the respective database table. So, for
-a class `Book`, you should have a database table called **books**. The Rails
-pluralization mechanisms are very powerful, being capable to pluralize (and
-singularize) both regular and irregular words. When using class names composed
-of two or more words, the model class name should follow the Ruby conventions,
-using the CamelCase form, while the table name must contain the words separated
+By default, Active Record uses some naming conventions to find out how the
+mapping between models and database tables should be created. Rails will
+pluralize your class names to find the respective database table. So, for
+a class `Book`, you should have a database table called **books**. The Rails
+pluralization mechanisms are very powerful, being capable to pluralize (and
+singularize) both regular and irregular words. When using class names composed
+of two or more words, the model class name should follow the Ruby conventions,
+using the CamelCase form, while the table name must contain the words separated
by underscores. Examples:
* Database Table - Plural with underscores separating words (e.g., `book_clubs`)
-* Model Class - Singular with the first letter of each word capitalized (e.g.,
+* Model Class - Singular with the first letter of each word capitalized (e.g.,
`BookClub`)
| Model / Class | Table / Schema |
@@ -92,33 +93,35 @@ by underscores. Examples:
### Schema Conventions
-Active Record uses naming conventions for the columns in database tables,
+Active Record uses naming conventions for the columns in database tables,
depending on the purpose of these columns.
-* **Foreign keys** - These fields should be named following the pattern
- `singularized_table_name_id` (e.g., `item_id`, `order_id`). These are the
- fields that Active Record will look for when you create associations between
+* **Foreign keys** - These fields should be named following the pattern
+ `singularized_table_name_id` (e.g., `item_id`, `order_id`). These are the
+ fields that Active Record will look for when you create associations between
your models.
-* **Primary keys** - By default, Active Record will use an integer column named
- `id` as the table's primary key. When using [Rails
- Migrations](migrations.html) to create your tables, this column will be
+* **Primary keys** - By default, Active Record will use an integer column named
+ `id` as the table's primary key. When using [Rails
+ Migrations](migrations.html) to create your tables, this column will be
automatically created.
-There are also some optional column names that will create additional features
+There are also some optional column names that will create additional features
to Active Record instances:
-* `created_at` - Automatically gets set to the current date and time when the
+* `created_at` - Automatically gets set to the current date and time when the
record is first created.
-* `updated_at` - Automatically gets set to the current date and time whenever
+* `updated_at` - Automatically gets set to the current date and time whenever
the record is updated.
-* `lock_version` - Adds [optimistic
- locking](http://api.rubyonrails.org/classes/ActiveRecord/Locking.html) to
+* `lock_version` - Adds [optimistic
+ locking](http://api.rubyonrails.org/classes/ActiveRecord/Locking.html) to
a model.
-* `type` - Specifies that the model uses [Single Table
+* `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
+* `(association_name)_type` - Stores the type for
+ [polymorphic associations](association_basics.html#polymorphic-associations).
+* `(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 (STI). If you are not using STI, try an analogous keyword like "context", that may still accurately describe the data you are modeling.
@@ -126,7 +129,7 @@ NOTE: While these column names are optional, they are in fact reserved by Active
Creating Active Record Models
-----------------------------
-It is very easy to create Active Record models. All you have to do is to
+It is very easy to create Active Record models. All you have to do is to
subclass the `ActiveRecord::Base` class and you're good to go:
```ruby
@@ -134,9 +137,9 @@ class Product < ActiveRecord::Base
end
```
-This will create a `Product` model, mapped to a `products` table at the
-database. By doing this you'll also have the ability to map the columns of each
-row in that table with the attributes of the instances of your model. Suppose
+This will create a `Product` model, mapped to a `products` table at the
+database. By doing this you'll also have the ability to map the columns of each
+row in that table with the attributes of the instances of your model. Suppose
that the `products` table was created using an SQL sentence like:
```sql
@@ -147,7 +150,7 @@ CREATE TABLE products (
);
```
-Following the table schema above, you would be able to write code like the
+Following the table schema above, you would be able to write code like the
following:
```ruby
@@ -159,11 +162,11 @@ puts p.name # "Some Book"
Overriding the Naming Conventions
---------------------------------
-What if you need to follow a different naming convention or need to use your
-Rails application with a legacy database? No problem, you can easily override
+What if you need to follow a different naming convention or need to use your
+Rails application with a legacy database? No problem, you can easily override
the default conventions.
-You can use the `ActiveRecord::Base.table_name=` method to specify the table
+You can use the `ActiveRecord::Base.table_name=` method to specify the table
name that should be used:
```ruby
@@ -172,8 +175,8 @@ class Product < ActiveRecord::Base
end
```
-If you do so, you will have to define manually the class name that is hosting
-the fixtures (class_name.yml) using the `set_fixture_class` method in your test
+If you do so, you will have to define manually the class name that is hosting
+the fixtures (class_name.yml) using the `set_fixture_class` method in your test
definition:
```ruby
@@ -184,7 +187,7 @@ class FunnyJoke < ActiveSupport::TestCase
end
```
-It's also possible to override the column that should be used as the table's
+It's also possible to override the column that should be used as the table's
primary key using the `ActiveRecord::Base.set_primary_key` method:
```ruby
@@ -196,17 +199,17 @@ end
CRUD: Reading and Writing Data
------------------------------
-CRUD is an acronym for the four verbs we use to operate on data: **C**reate,
-**R**ead, **U**pdate and **D**elete. Active Record automatically creates methods
+CRUD is an acronym for the four verbs we use to operate on data: **C**reate,
+**R**ead, **U**pdate and **D**elete. Active Record automatically creates methods
to allow an application to read and manipulate data stored within its tables.
### Create
-Active Record objects can be created from a hash, a block or have their
-attributes manually set after creation. The `new` method will return a new
+Active Record objects can be created from a hash, a block or have their
+attributes manually set after creation. The `new` method will return a new
object while `create` will return the object and save it to the database.
-For example, given a model `User` with attributes of `name` and `occupation`,
+For example, given a model `User` with attributes of `name` and `occupation`,
the `create` method call will create and save a new record into the database:
```ruby
@@ -223,7 +226,7 @@ user.occupation = "Code Artist"
A call to `user.save` will commit the record to the database.
-Finally, if a block is provided, both `create` and `new` will yield the new
+Finally, if a block is provided, both `create` and `new` will yield the new
object to that block for initialization:
```ruby
@@ -235,7 +238,7 @@ end
### Read
-Active Record provides a rich API for accessing data within a database. Below
+Active Record provides a rich API for accessing data within a database. Below
are a few examples of different data access methods provided by Active Record.
```ruby
@@ -258,12 +261,12 @@ david = User.find_by_name('David')
users = User.where(name: 'David', occupation: 'Code Artist').order('created_at DESC')
```
-You can learn more about querying an Active Record model in the [Active Record
+You can learn more about querying an Active Record model in the [Active Record
Query Interface](active_record_querying.html) guide.
### Update
-Once an Active Record object has been retrieved, its attributes can be modified
+Once an Active Record object has been retrieved, its attributes can be modified
and it can be saved to the database.
```ruby
@@ -272,7 +275,7 @@ user.name = 'Dave'
user.save
```
-A shorthand for this is to use a hash mapping attribute names to the desired
+A shorthand for this is to use a hash mapping attribute names to the desired
value, like so:
```ruby
@@ -280,8 +283,8 @@ user = User.find_by_name('David')
user.update(name: 'Dave')
```
-This is most useful when updating several attributes at once. If, on the other
-hand, you'd like to update several records in bulk, you may find the
+This is most useful when updating several attributes at once. If, on the other
+hand, you'd like to update several records in bulk, you may find the
`update_all` class method useful:
```ruby
@@ -290,7 +293,7 @@ User.update_all "max_login_attempts = 3, must_change_password = 'true'"
### Delete
-Likewise, once retrieved an Active Record object can be destroyed which removes
+Likewise, once retrieved an Active Record object can be destroyed which removes
it from the database.
```ruby
@@ -301,46 +304,46 @@ user.destroy
Validations
-----------
-Active Record allows you to validate the state of a model before it gets written
-into the database. There are several methods that you can use to check your
-models and validate that an attribute value is not empty, is unique and not
+Active Record allows you to validate the state of a model before it gets written
+into the database. There are several methods that you can use to check your
+models and validate that an attribute value is not empty, is unique and not
already in the database, follows a specific format and many more.
-Validation is a very important issue to consider when persisting to database, so
-the methods `create`, `save` and `update` take it into account when
-running: they return `false` when validation fails and they didn't actually
-perform any operation on database. All of these have a bang counterpart (that
-is, `create!`, `save!` and `update!`), which are stricter in that
-they raise the exception `ActiveRecord::RecordInvalid` if validation fails.
+Validation is a very important issue to consider when persisting to database, so
+the methods `create`, `save` and `update` take it into account when
+running: they return `false` when validation fails and they didn't actually
+perform any operation on database. All of these have a bang counterpart (that
+is, `create!`, `save!` and `update!`), which are stricter in that
+they raise the exception `ActiveRecord::RecordInvalid` if validation fails.
A quick example to illustrate:
```ruby
class User < ActiveRecord::Base
- validates_presence_of :name
+ validates :name, presence: true
end
User.create # => false
User.create! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
```
-You can learn more about validations in the [Active Record Validations
+You can learn more about validations in the [Active Record Validations
guide](active_record_validations.html).
Callbacks
---------
-Active Record callbacks allow you to attach code to certain events in the
-life-cycle of your models. This enables you to add behavior to your models by
-transparently executing code when those events occur, like when you create a new
-record, update it, destroy it and so on. You can learn more about callbacks in
+Active Record callbacks allow you to attach code to certain events in the
+life-cycle of your models. This enables you to add behavior to your models by
+transparently executing code when those events occur, like when you create a new
+record, update it, destroy it and so on. You can learn more about callbacks in
the [Active Record Callbacks guide](active_record_callbacks.html).
Migrations
----------
-Rails provides a domain-specific language for managing a database schema called
-migrations. Migrations are stored in files which are executed against any
-database that Active Record support using `rake`. Here's a migration that
+Rails provides a domain-specific language for managing a database schema called
+migrations. Migrations are stored in files which are executed against any
+database that Active Record support using `rake`. Here's a migration that
creates a table:
```ruby
@@ -361,10 +364,10 @@ class CreatePublications < ActiveRecord::Migration
end
```
-Rails keeps track of which files have been committed to the database and
+Rails keeps track of which files have been committed to the database and
provides rollback features. To actually create the table, you'd run `rake db:migrate`
and to roll it back, `rake db:rollback`.
-Note that the above code is database-agnostic: it will run in MySQL, postgresql,
-Oracle and others. You can learn more about migrations in the [Active Record
+Note that the above code is database-agnostic: it will run in MySQL, postgresql,
+Oracle and others. You can learn more about migrations in the [Active Record
Migrations guide](migrations.html)
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index 448f0e1f9a..43df544e28 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -547,35 +547,7 @@ This directive is available if the core module that provides this feature was co
If you're compiling nginx with Phusion Passenger you'll need to pass that option when prompted.
-Apache is also able to serve the [gzipped](http://en.wikipedia.org/wiki/Gzip) version of your assets; however, it requires a bit more work:
-
-```apache
-<LocationMatch "^/assets/.*$">
- Header unset ETag
- FileETag None
-
- # RFC says only cache for 1 year
- ExpiresActive On
- ExpiresDefault "access plus 1 year"
-
- RewriteEngine On
- RewriteCond %{HTTP:Accept-Encoding} gzip
- RewriteCond %{HTTP_USER_AGENT} !Konqueror
- RewriteCond %{REQUEST_FILENAME}.gz -f
- RewriteRule ^(.+).(css|js)$ $1.$2.gz [QSA,L]
-</LocationMatch>
-
-<FilesMatch \.css\.gz>
- ForceType text/css
-</FilesMatch>
-
-<FilesMatch \.js\.gz>
- ForceType application/javascript
-</FilesMatch>
-AddEncoding gzip .gz
-```
-
-NOTE: You will need to make sure `mod_headers`, `mod_mime` and `mod_rewrite` are loaded; otherwise, the above configuration will fail.
+A robust configuration for Apache is possible but tricky; please Google around. (Or help update this Guide if you have a good example configuration for Apache.)
### Local Precompilation
diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md
index abab3dd983..e1fc3d0f53 100644
--- a/guides/source/caching_with_rails.md
+++ b/guides/source/caching_with_rails.md
@@ -5,8 +5,8 @@ This guide will teach you what you need to know about avoiding that expensive ro
After reading this guide, you will know:
-* Page, action, and fragment caching.
-* Sweepers.
+* Page and action caching (moved to separate gems as of Rails 4).
+* Fragment caching.
* Alternative cache stores.
* Conditional GET support.
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index 4711186522..7b7f5963fd 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -445,12 +445,12 @@ NOTE. When using specific annotations and custom annotations, the annotation nam
By default, `rake notes` will look in the `app`, `config`, `lib`, `bin` and `test` directories. If you would like to search other directories, you can provide them as a comma separated list in an environment variable `SOURCE_ANNOTATION_DIRECTORIES`.
```bash
-$ export SOURCE_ANNOTATION_DIRECTORIES='rspec,vendor'
+$ export SOURCE_ANNOTATION_DIRECTORIES='spec,vendor'
$ rake notes
(in /home/foobar/commandsapp)
app/models/user.rb:
* [ 35] [FIXME] User should have a subscription at this point
-rspec/model/user_spec.rb:
+spec/models/user_spec.rb:
* [122] [TODO] Verify the user that has a subscription works
```
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 9ea493325d..a0ab707b51 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -268,7 +268,7 @@ config.middleware.delete "Rack::MethodOverride"
* `config.active_record.lock_optimistically` controls whether Active Record will use optimistic locking and is true by default.
-* +config.active_record.cache_timestamp_format+ controls the format of the timestamp value in the cache key. Default is +:number+.
+* `config.active_record.cache_timestamp_format` controls the format of the timestamp value in the cache key. Default is `:number`.
The MySQL adapter adds one additional configuration option:
diff --git a/guides/source/credits.html.erb b/guides/source/credits.html.erb
index ff76fa2b85..34be07ef81 100644
--- a/guides/source/credits.html.erb
+++ b/guides/source/credits.html.erb
@@ -28,7 +28,7 @@ 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="https://github.com/radar">his GitHub page</a> and he also tweets prolifically as <a href="http://twitter.com/ryanbigg">@ryanbigg</a>.
+ Ryan Bigg works as the Community Manager at <a href="http://spreecommerce.com">Spree Commerce</a> and has been working with Rails since 2006. He's the author of <a href="https://leanpub.com/multi-tenancy-rails">Multi Tenancy With Rails</a> and co-author of <a href="http://manning.com/bigg2">Rails 4 in Action</a>. He's written many gems which can be seen on <a href="https://github.com/radar">his GitHub page</a> and he also tweets prolifically as <a href="http://twitter.com/ryanbigg">@ryanbigg</a>.
<% end %>
<%= author('Oscar Del Ben', 'oscardelben', 'oscardelben.jpg') do %>
diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md
index 6699098e51..8f1d2922ac 100644
--- a/guides/source/debugging_rails_applications.md
+++ b/guides/source/debugging_rails_applications.md
@@ -655,21 +655,18 @@ Plugins for Debugging
There are some Rails plugins to help you to find errors and debug your application. Here is a list of useful plugins for debugging:
-* [Footnotes](https://github.com/josevalim/rails-footnotes:) Every Rails page has footnotes that give request information and link back to your source via TextMate.
-* [Query Trace](https://github.com/ntalbott/query_trace/tree/master:) Adds query origin tracing to your logs.
-* [Query Reviewer](https://github.com/nesquena/query_reviewer:) This rails plugin not only runs "EXPLAIN" before each of your select queries in development, but provides a small DIV in the rendered output of each page with the summary of warnings for each query that it analyzed.
-* [Exception Notifier](https://github.com/smartinez87/exception_notification/tree/master:) Provides a mailer object and a default set of templates for sending email notifications when errors occur in a Rails application.
+* [Footnotes](https://github.com/josevalim/rails-footnotes) Every Rails page has footnotes that give request information and link back to your source via TextMate.
+* [Query Trace](https://github.com/ntalbott/query_trace/tree/master) Adds query origin tracing to your logs.
+* [Query Reviewer](https://github.com/nesquena/query_reviewer) This rails plugin not only runs "EXPLAIN" before each of your select queries in development, but provides a small DIV in the rendered output of each page with the summary of warnings for each query that it analyzed.
+* [Exception Notifier](https://github.com/smartinez87/exception_notification/tree/master) Provides a mailer object and a default set of templates for sending email notifications when errors occur in a Rails application.
References
----------
* [ruby-debug Homepage](http://bashdb.sourceforge.net/ruby-debug/home-page.html)
* [debugger Homepage](https://github.com/cldwalker/debugger)
-* [Article: Debugging a Rails application with ruby-debug](http://www.sitepoint.com/article/debug-rails-app-ruby-debug/)
-* [ruby-debug Basics screencast](http://brian.maybeyoureinsane.net/blog/2007/05/07/ruby-debug-basics-screencast/)
+* [Article: Debugging a Rails application with ruby-debug](http://www.sitepoint.com/debug-rails-app-ruby-debug/)
* [Ryan Bates' debugging ruby (revised) screencast](http://railscasts.com/episodes/54-debugging-ruby-revised)
* [Ryan Bates' stack trace screencast](http://railscasts.com/episodes/24-the-stack-trace)
* [Ryan Bates' logger screencast](http://railscasts.com/episodes/56-the-logger)
* [Debugging with ruby-debug](http://bashdb.sourceforge.net/ruby-debug.html)
-* [ruby-debug cheat sheet](http://cheat.errtheblog.com/s/rdebug/)
-* [Ruby on Rails Wiki: How to Configure Logging](http://wiki.rubyonrails.org/rails/pages/HowtoConfigureLogging)
diff --git a/guides/source/development_dependencies_install.md b/guides/source/development_dependencies_install.md
index 6493c1e1ec..14ca44d2a1 100644
--- a/guides/source/development_dependencies_install.md
+++ b/guides/source/development_dependencies_install.md
@@ -21,9 +21,9 @@ In case you can't use the Rails development box, see section above, these are th
Ruby on Rails uses Git for source code control. The [Git homepage](http://git-scm.com/) has installation instructions. There are a variety of resources on the net that will help you get familiar with Git:
-* [Try Git course](http://try.github.com/) is an interactive course that will teach you the basics.
+* [Try Git course](http://try.github.io/) is an interactive course that will teach you the basics.
* The [official Documentation](http://git-scm.com/documentation) is pretty comprehensive and also contains some videos with the basics of Git
-* [Everyday Git](http://schacon.github.com/git/everyday.html) will teach you just enough about Git to get by.
+* [Everyday Git](http://schacon.github.io/git/everyday.html) will teach you just enough about Git to get by.
* The [PeepCode screencast](https://peepcode.com/products/git) on Git ($9) is easier to follow.
* [GitHub](http://help.github.com) offers links to a variety of Git resources.
* [Pro Git](http://git-scm.com/book) is an entire book about Git with a Creative Commons license.
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index 4fce08e839..1b16f4e516 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -36,6 +36,11 @@
name: Views
documents:
-
+ name: Action View Overview
+ url: action_view_overview.html
+ description: This guide provides an introduction to Action View and introduces a few of the more common view helpers.
+ work_in_progress: true
+ -
name: Layouts and Rendering in Rails
url: layouts_and_rendering.html
description: This guide covers the basic layout features of Action Controller and Action View, including rendering and redirecting, using content_for blocks, and working with partials.
diff --git a/guides/source/engines.md b/guides/source/engines.md
index ac76f00832..663e59b5c3 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -461,7 +461,7 @@ NOTE: Other engines, such as Devise, handle this a little differently by making
The engine contains migrations for the `blorgh_posts` and `blorgh_comments` table which need to be created in the application's database so that the engine's models can query them correctly. To copy these migrations into the application use this command:
```bash
-$ rake blorgh:install:migrations
+$ rake blorgh_engine:install:migrations
```
If you have multiple engines that need migrations copied over, use `railties:install:migrations` instead:
@@ -612,50 +612,50 @@ This section covers how to make the `User` class configurable, followed by gener
#### Setting configuration settings in the application
-The next step is to make the class that represents a `User` in the application customizable for the engine. This is because, as explained before, that class may not always be `User`. To make this customizable, the engine will have a configuration setting called `user_class` that will be used to specify what the class representing users is inside the application.
+The next step is to make the class that represents a `User` in the application customizable for the engine. This is because, as explained before, that class may not always be `User`. To make this customizable, the engine will have a configuration setting called `author_class` that will be used to specify what the class representing users is inside the application.
To define this configuration setting, you should use a `mattr_accessor` inside the `Blorgh` module for the engine, located at `lib/blorgh.rb` inside the engine. Inside this module, put this line:
```ruby
-mattr_accessor :user_class
+mattr_accessor :author_class
```
-This method works like its brothers `attr_accessor` and `cattr_accessor`, but provides a setter and getter method on the module with the specified name. To use it, it must be referenced using `Blorgh.user_class`.
+This method works like its brothers `attr_accessor` and `cattr_accessor`, but provides a setter and getter method on the module with the specified name. To use it, it must be referenced using `Blorgh.author_class`.
The next step is switching the `Blorgh::Post` model over to this new setting. For the `belongs_to` association inside this model (`app/models/blorgh/post.rb`), it will now become this:
```ruby
-belongs_to :author, class_name: Blorgh.user_class
+belongs_to :author, class_name: Blorgh.author_class
```
The `set_author` method also located in this class should also use this class:
```ruby
-self.author = Blorgh.user_class.constantize.find_or_create_by(name: author_name)
+self.author = Blorgh.author_class.constantize.find_or_create_by(name: author_name)
```
-To save having to call `constantize` on the `user_class` result all the time, you could instead just override the `user_class` getter method inside the `Blorgh` module in the `lib/blorgh.rb` file to always call `constantize` on the saved value before returning the result:
+To save having to call `constantize` on the `author_class` result all the time, you could instead just override the `author_class` getter method inside the `Blorgh` module in the `lib/blorgh.rb` file to always call `constantize` on the saved value before returning the result:
```ruby
-def self.user_class
- @@user_class.constantize
+def self.author_class
+ @@author_class.constantize
end
```
This would then turn the above code for `set_author` into this:
```ruby
-self.author = Blorgh.user_class.find_or_create_by(name: author_name)
+self.author = Blorgh.author_class.find_or_create_by(name: author_name)
```
-Resulting in something a little shorter, and more implicit in its behavior. The `user_class` method should always return a `Class` object.
+Resulting in something a little shorter, and more implicit in its behavior. The `author_class` method should always return a `Class` object.
-Since we changed the `user_class` method to no longer return a
+Since we changed the `author_class` method to no longer return a
`String` but a `Class` we must also modify our `belongs_to` definition
in the `Blorgh::Post` model:
```ruby
-belongs_to :author, class_name: Blorgh.user_class.to_s
+belongs_to :author, class_name: Blorgh.author_class.to_s
```
To set this configuration setting within the application, an initializer should be used. By using an initializer, the configuration will be set up before the application starts and calls the engine's models which may depend on this configuration setting existing.
@@ -663,7 +663,7 @@ To set this configuration setting within the application, an initializer should
Create a new initializer at `config/initializers/blorgh.rb` inside the application where the `blorgh` engine is installed and put this content in it:
```ruby
-Blorgh.user_class = "User"
+Blorgh.author_class = "User"
```
WARNING: It's very important here to use the `String` version of the class, rather than the class itself. If you were to use the class, Rails would attempt to load that class and then reference the related table, which could lead to problems if the table wasn't already existing. Therefore, a `String` should be used and then converted to a class using `constantize` in the engine later on.
diff --git a/guides/source/form_helpers.md b/guides/source/form_helpers.md
index 3f16ebcf1d..a4dab39d55 100644
--- a/guides/source/form_helpers.md
+++ b/guides/source/form_helpers.md
@@ -221,7 +221,7 @@ Upon form submission the value entered by the user will be stored in `params[:pe
WARNING: You must pass the name of an instance variable, i.e. `:person` or `"person"`, not an actual instance of your model object.
-Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the [Active Record Validations and Callbacks](./active_record_validations_callbacks.html#displaying-validation-errors-in-the-view) guide.
+Rails provides helpers for displaying the validation errors associated with a model object. These are covered in detail by the [Active Record Validations](./active_record_validations.html#displaying-validation-errors-in-views) guide.
### Binding a Form to an Object
@@ -836,17 +836,14 @@ Active Record provides model level support via the `accepts_nested_attributes_f
class Person < ActiveRecord::Base
has_many :addresses
accepts_nested_attributes_for :addresses
-
- attr_accessible :name, :addresses_attributes
end
class Address < ActiveRecord::Base
belongs_to :person
- attr_accessible :kind, :street
end
```
-This creates an `addresses_attributes=` method on `Person` that allows you to create, update and (optionally) destroy addresses. When using `attr_accessible` or `attr_protected` you must mark `addresses_attributes` as accessible as well as the other attributes of `Person` and `Address` that should be mass assigned.
+This creates an `addresses_attributes=` method on `Person` that allows you to create, update and (optionally) destroy addresses.
### Building the Form
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index 3881bb1195..d49a30d02f 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -1043,7 +1043,7 @@ REST convention, so to create a new `Post` object it will look for a
route named `posts_path`, and to update a `Post` object it will look for
a route named `post_path` and pass the current object. Similarly, rails
knows that it should create new objects via POST and update them via
-PUT.
+PATCH.
If you run `rake routes` from the console you'll see that we already
have a `posts_path` route, which was created automatically by Rails when we
@@ -1054,13 +1054,13 @@ received an error before. With your server running you can view your routes by v
```bash
$ rake routes
- posts GET /posts(.:format) posts#index
-posts_new GET /posts/new(.:format) posts#new
- POST /posts(.:format) posts#create
- GET /posts/:id(.:format) posts#show
- GET /posts/:id/edit(.:format) posts#edit
- PUT /posts/:id(.:format) posts#update
- root / welcome#index
+ posts GET /posts(.:format) posts#index
+posts_new GET /posts/new(.:format) posts#new
+ POST /posts(.:format) posts#create
+ GET /posts/:id(.:format) posts#show
+ GET /posts/:id/edit(.:format) posts#edit
+ PATCH /posts/:id(.:format) posts#update
+ root / welcome#index
```
To fix this, open `config/routes.rb` and modify the `get "posts/:id"`
@@ -1197,6 +1197,7 @@ $ rake routes
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
+ PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
root / welcome#index
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index 5304ca4285..d187d3a03a 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -837,6 +837,28 @@ en:
NOTE: In order to use this helper, you need to install [DynamicForm](https://github.com/joelmoss/dynamic_form)
gem by adding this line to your Gemfile: `gem 'dynamic_form'`.
+### Translations for Action Mailer E-Mail Subjects
+
+If you don't pass a subject to the `mail` method, Action Mailer will try to find
+it in your translations. The performed lookup will use the pattern
+`<mailer_scope>.<action_name>.subject` to construct the key.
+
+```ruby
+# user_mailer.rb
+class UserMailer < ActionMailer::Base
+ def welcome(user)
+ #...
+ end
+end
+```
+
+```yaml
+en:
+ user_mailer:
+ welcome:
+ subject: "Welcome to Rails Guides!"
+```
+
### Overview of Other Built-In Methods that Provide I18n Support
Rails uses fixed strings and other localizations, such as format strings and other format information in a couple of helpers. Here's a brief overview.
diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md
index a3b3472701..addc0a5430 100644
--- a/guides/source/layouts_and_rendering.md
+++ b/guides/source/layouts_and_rendering.md
@@ -1,7 +1,7 @@
Layouts and Rendering in Rails
==============================
-This guide covers the basic layout features of Action Controller and Action View. By referring to this guide, you will be able to:
+This guide covers the basic layout features of Action Controller and Action View.
After reading this guide, you will know:
@@ -319,7 +319,62 @@ render status: 500
render status: :forbidden
```
-Rails understands both numeric and symbolic status codes.
+Rails understands both numeric status codes and the corresponding symbols shown below:
+
+| HTTP Status Code | Symbol |
+| ---------------- | -------------------------------- |
+| 100 | :continue |
+| 101 | :switching_protocols |
+| 102 | :processing |
+| 200 | :ok |
+| 201 | :created |
+| 202 | :accepted |
+| 203 | :non_authoritative_information |
+| 204 | :no_content |
+| 205 | :reset_content |
+| 206 | :partial_content |
+| 207 | :multi_status |
+| 226 | :im_used |
+| 300 | :multiple_choices |
+| 301 | :moved_permanently |
+| 302 | :found |
+| 303 | :see_other |
+| 304 | :not_modified |
+| 305 | :use_proxy |
+| 306 | :reserved |
+| 307 | :temporary_redirect |
+| 400 | :bad_request |
+| 401 | :unauthorized |
+| 402 | :payment_required |
+| 403 | :forbidden |
+| 404 | :not_found |
+| 405 | :method_not_allowed |
+| 406 | :not_acceptable |
+| 407 | :proxy_authentication_required |
+| 408 | :request_timeout |
+| 409 | :conflict |
+| 410 | :gone |
+| 411 | :length_required |
+| 412 | :precondition_failed |
+| 413 | :request_entity_too_large |
+| 414 | :request_uri_too_long |
+| 415 | :unsupported_media_type |
+| 416 | :requested_range_not_satisfiable |
+| 417 | :expectation_failed |
+| 418 | :i'm_a_teapot |
+| 422 | :unprocessable_entity |
+| 423 | :locked |
+| 424 | :failed_dependency |
+| 426 | :upgrade_required |
+| 500 | :internal_server_error |
+| 501 | :not_implemented |
+| 502 | :bad_gateway |
+| 503 | :service_unavailable |
+| 504 | :gateway_timeout |
+| 505 | :http_version_not_supported |
+| 506 | :variant_also_negotiates |
+| 507 | :insufficient_storage |
+| 510 | :not_extended |
##### The `:location` Option
diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md
index 77138d8871..b548eaede8 100644
--- a/guides/source/rails_application_templates.md
+++ b/guides/source/rails_application_templates.md
@@ -13,7 +13,7 @@ After reading this guide, you will know:
Usage
-----
-To apply a template, you need to provide the Rails generator with the location of the template you wish to apply, using -m option. This can either be path to a file or a URL.
+To apply a template, you need to provide the Rails generator with the location of the template you wish to apply using the -m option. This can either be a path to a file or a URL.
```bash
$ rails new blog -m ~/template.rb
@@ -30,7 +30,7 @@ $ rake rails:template LOCATION=http://example.com/template.rb
Template API
------------
-Rails templates API is very self explanatory and easy to understand. Here's an example of a typical Rails template:
+The Rails templates API is easy to understand. Here's an example of a typical Rails template:
```ruby
# template.rb
@@ -43,7 +43,7 @@ git add: "."
git commit: %Q{ -m 'Initial commit' }
```
-The following sections outlines the primary methods provided by the API:
+The following sections outline the primary methods provided by the API:
### gem(*args)
@@ -66,7 +66,7 @@ bundle install
Wraps gem entries inside a group.
-For example, if you want to load `rspec-rails` only in `development` and `test` group:
+For example, if you want to load `rspec-rails` only in the `development` and `test` groups:
```ruby
gem_group :development, :test do
@@ -100,7 +100,7 @@ A block can be used in place of the `data` argument.
Adds an initializer to the generated application’s `config/initializers` directory.
-Lets say you like using `Object#not_nil?` and `Object#not_blank?`:
+Let's say you like using `Object#not_nil?` and `Object#not_blank?`:
```ruby
initializer 'bloatlol.rb', <<-CODE
@@ -116,9 +116,9 @@ initializer 'bloatlol.rb', <<-CODE
CODE
```
-Similarly `lib()` creates a file in the `lib/` directory and `vendor()` creates a file in the `vendor/` directory.
+Similarly, `lib()` creates a file in the `lib/` directory and `vendor()` creates a file in the `vendor/` directory.
-There is even `file()`, which accepts a relative path from `Rails.root` and creates all the directories/file needed:
+There is even `file()`, which accepts a relative path from `Rails.root` and creates all the directories/files needed:
```ruby
file 'app/components/foo.rb', <<-CODE
@@ -127,7 +127,7 @@ file 'app/components/foo.rb', <<-CODE
CODE
```
-That’ll create `app/components` directory and put `foo.rb` in there.
+That’ll create the `app/components` directory and put `foo.rb` in there.
### rakefile(filename, data = nil, &block)
@@ -179,7 +179,7 @@ rake "db:migrate", env: 'production'
### route(routing_code)
-Adds a routing entry to the `config/routes.rb` file. In above steps, we generated a person scaffold and also removed `README.rdoc`. Now to make `PeopleController#index` as the default page for the application:
+Adds a routing entry to the `config/routes.rb` file. In the steps above, we generated a person scaffold and also removed `README.rdoc`. Now, to make `PeopleController#index` the default page for the application:
```ruby
route "root to: 'person#index'"
@@ -197,7 +197,7 @@ end
### ask(question)
-`ask()` gives you a chance to get some feedback from the user and use it in your templates. Lets say you want your user to name the new shiny library you’re adding:
+`ask()` gives you a chance to get some feedback from the user and use it in your templates. Let's say you want your user to name the new shiny library you’re adding:
```ruby
lib_name = ask("What do you want to call the shiny library ?")
@@ -211,7 +211,7 @@ CODE
### yes?(question) or no?(question)
-These methods let you ask questions from templates and decide the flow based on the user’s answer. Lets say you want to freeze rails only if the user want to:
+These methods let you ask questions from templates and decide the flow based on the user’s answer. Let's say you want to freeze rails only if the user wants to:
```ruby
rake("rails:freeze:gems") if yes?("Freeze rails gems?")
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index d8477d89e3..de8f3f483f 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -28,7 +28,10 @@ Rails on Rack
### Rails Application's Rack Object
-`ApplicationName::Application` is the primary Rack application object of a Rails application. Any Rack compliant web server should be using `ApplicationName::Application` object to serve a Rails application.
+`ApplicationName::Application` is the primary Rack application object of a Rails
+application. Any Rack compliant web server should be using
+`ApplicationName::Application` object to serve a Rails
+application. `Rails.application` refers to the same application object.
### `rails server`
@@ -79,11 +82,11 @@ To use `rackup` instead of Rails' `rails server`, you can put the following insi
```ruby
# Rails.root/config.ru
-require "config/environment"
+require ::File.expand_path('../config/environment', __FILE__)
use Rack::Debugger
use Rack::ContentLength
-run ApplicationName::Application
+run Rails.application
```
And start the server:
@@ -101,7 +104,7 @@ $ rackup --help
Action Dispatcher Middleware Stack
----------------------------------
-Many of Action Dispatchers's internal components are implemented as Rack middlewares. `Rails::Application` uses `ActionDispatch::MiddlewareStack` to combine various internal and external middlewares to form a complete Rails Rack application.
+Many of Action Dispatcher's internal components are implemented as Rack middlewares. `Rails::Application` uses `ActionDispatch::MiddlewareStack` to combine various internal and external middlewares to form a complete Rails Rack application.
NOTE: `ActionDispatch::MiddlewareStack` is Rails equivalent of `Rack::Builder`, but built for better flexibility and more features to meet Rails' requirements.
@@ -324,7 +327,7 @@ config.middleware.clear
```ruby
# config.ru
use MyOwnStackFromScratch
-run ApplicationName::Application
+run Rails.application
```
Resources
@@ -332,7 +335,7 @@ Resources
### Learning Rack
-* [Official Rack Website](http://rack.github.com)
+* [Official Rack Website](http://rack.github.io)
* [Introducing Rack](http://chneukirchen.org/blog/archive/2007/02/introducing-rack.html)
* [Ruby on Rack #1 - Hello Rack!](http://m.onkey.org/ruby-on-rack-1-hello-rack)
* [Ruby on Rack #2 - The Builder](http://m.onkey.org/ruby-on-rack-2-the-builder)
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 04098f0a5c..f4cb8fe15b 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -138,6 +138,12 @@ Sometimes, you have a resource that clients always look up without referencing a
get 'profile', to: 'users#show'
```
+Passing a `String` to `match` will expect a `controller#action` format, while passing a `Symbol` will map directly to an action:
+
+```ruby
+get 'profile', to: :show
+```
+
This resourceful route:
```ruby
diff --git a/guides/source/security.md b/guides/source/security.md
index d56ce47b3c..b2d09369e2 100644
--- a/guides/source/security.md
+++ b/guides/source/security.md
@@ -1,4 +1,4 @@
-Ruby On Rails Security Guide
+Ruby on Rails Security Guide
============================
This manual describes common security problems in web applications and how to avoid them with Rails.
diff --git a/guides/source/testing.md b/guides/source/testing.md
index d5efadec6c..4c0a61bc5e 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -128,12 +128,12 @@ When you use `rails generate scaffold`, for a resource among other things it cre
$ rails generate scaffold post title:string body:text
...
create app/models/post.rb
-create test/unit/post_test.rb
+create test/models/post_test.rb
create test/fixtures/posts.yml
...
```
-The default test stub in `test/unit/post_test.rb` looks like this:
+The default test stub in `test/models/post_test.rb` looks like this:
```ruby
require 'test_helper'
@@ -714,17 +714,17 @@ class UserFlowsTest < ActionDispatch::IntegrationTest
test "login and browse site" do
- # User avs logs in
- avs = login(:david)
+ # User david logs in
+ david = login(:david)
# User guest logs in
guest = login(:guest)
# Both are now available in different sessions
- assert_equal 'Welcome david!', avs.flash[:notice]
+ assert_equal 'Welcome david!', david.flash[:notice]
assert_equal 'Welcome guest!', guest.flash[:notice]
- # User avs can browse site
- avs.browses_site
+ # User david can browse site
+ david.browses_site
# User guest can browse site as well
guest.browses_site
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index a8182617f3..51d6775c3e 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -71,7 +71,7 @@ Rails 4.0 extracted Active Resource to its own gem. If you still need the featur
* Rails 4.0 has changed how errors attach with the `ActiveModel::Validations::ConfirmationValidator`. Now when confirmation validations fail, the error will be attached to `:#{attribute}_confirmation` instead of `attribute`.
-* Rails 4.0 has changed `ActiveModel::Serializers::JSON.include_root_in_json` default value to `false`. Now, Active Model Serializers and Active Record objects have the same default behavior. This means that you can comment or remove the following option in the `config/initializers/wrap_parameters.rb` file:
+* Rails 4.0 has changed `ActiveModel::Serializers::JSON.include_root_in_json` default value to `false`. Now, Active Model Serializers and Active Record objects have the same default behaviour. This means that you can comment or remove the following option in the `config/initializers/wrap_parameters.rb` file:
```ruby
# Disable root element in JSON by default.
@@ -320,7 +320,7 @@ config.assets.debug = true
Again, most of the changes below are for the asset pipeline. You can read more about these in the [Asset Pipeline](asset_pipeline.html) guide.
```ruby
-# Compress JavaScript and CSS
+# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
diff --git a/rails.gemspec b/rails.gemspec
index a223ea1413..a43dde26e4 100644
--- a/rails.gemspec
+++ b/rails.gemspec
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
- s.files = ['README.rdoc'] + Dir['guides/**/*']
+ s.files = ['README.md'] + Dir['guides/**/*']
s.add_dependency 'activesupport', version
s.add_dependency 'actionpack', version
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index e4a08f68c1..f67177a047 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -58,7 +58,7 @@
* Improve service pages with new layout (404, etc).
- *Stanislav Sobolev*
+ *Stanislav Sobolev*
## Rails 4.0.0.beta1 (February 25, 2013) ##
diff --git a/railties/lib/rails/app_rails_loader.rb b/railties/lib/rails/app_rails_loader.rb
index aae628290d..4a17803f1c 100644
--- a/railties/lib/rails/app_rails_loader.rb
+++ b/railties/lib/rails/app_rails_loader.rb
@@ -4,28 +4,7 @@ module Rails
module AppRailsLoader
RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"]
EXECUTABLES = ['bin/rails', 'script/rails']
-
- def self.exec_app_rails
- original_cwd = Dir.pwd
-
- until exe = find_executable
- # If we exhaust the search there is no executable, this could be a
- # call to generate a new application, so restore the original cwd.
- Dir.chdir(original_cwd) and return if Pathname.new(Dir.pwd).root?
-
- # Otherwise keep moving upwards in search of a executable.
- Dir.chdir('..')
- end
-
- contents = File.read(exe)
-
- # This is the Rails executable, let's use it
- if contents =~ /(APP|ENGINE)_PATH/
- exec RUBY, exe, *ARGV
-
- # This is a Bundler binstub. Stop and explain how to upgrade.
- elsif exe =~ /bin\/rails$/ && contents =~ /This file was generated by Bundler/
- $stderr.puts <<-end_bin_upgrade_warning
+ BUNDLER_WARNING = <<EOS
Looks like your app's ./bin/rails is a stub that was generated by Bundler.
In Rails 4, your app's bin/ directory contains executables that are versioned
@@ -45,14 +24,34 @@ generate it and add it to source control:
bundle binstubs some-gem-name
git add bin/new-executable
- end_bin_upgrade_warning
+EOS
+
+ def self.exec_app_rails
+ original_cwd = Dir.pwd
+
+ loop do
+ if exe = find_executable
+ contents = File.read(exe)
+
+ if contents =~ /(APP|ENGINE)_PATH/
+ exec RUBY, exe, *ARGV
+ break # non reachable, hack to be able to stub exec in the test suite
+ elsif exe.end_with?('bin/rails') && contents.include?('This file was generated by Bundler')
+ $stderr.puts(BUNDLER_WARNING)
+ Object.const_set(:APP_PATH, File.expand_path('config/application', Dir.pwd))
+ require File.expand_path('../boot', APP_PATH)
+ require 'rails/commands'
+ break
+ end
+ end
- Object.const_set(:APP_PATH, File.expand_path('config/application', Dir.pwd))
- require File.expand_path('../boot', APP_PATH)
- require 'rails/commands'
+ # If we exhaust the search there is no executable, this could be a
+ # call to generate a new application, so restore the original cwd.
+ Dir.chdir(original_cwd) and return if Pathname.new(Dir.pwd).root?
+
+ # Otherwise keep moving upwards in search of a executable.
+ Dir.chdir('..')
end
- rescue SystemCallError
- # could not chdir, no problem just return
end
def self.find_executable
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index b62d1fff14..4fd1f00294 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -116,7 +116,7 @@ module Rails
def database_gemfile_entry
options[:skip_active_record] ? "" :
- <<-GEMFILE.gsub(/^ {12}/, '').strip
+ <<-GEMFILE.strip_heredoc.chomp
# Use #{options[:database]} as the database for ActiveRecord
gem '#{gem_for_database}'
GEMFILE
@@ -182,20 +182,20 @@ module Rails
return if options[:skip_sprockets]
gemfile = if options.dev? || options.edge?
- <<-GEMFILE.gsub(/^ {12}/, '')
+ <<-GEMFILE.strip_heredoc
# Use edge version of sprockets-rails
gem 'sprockets-rails', github: 'rails/sprockets-rails'
# Use SCSS for stylesheets
- gem 'sass-rails', github: 'rails/sass-rails'
+ gem 'sass-rails', github: 'rails/sass-rails'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '~> 1.3'
GEMFILE
else
- <<-GEMFILE.gsub(/^ {12}/, '')
+ <<-GEMFILE.strip_heredoc
# Use SCSS for stylesheets
- gem 'sass-rails', '~> 4.0.0.beta1'
+ gem 'sass-rails', '~> 4.0.0.beta1'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '~> 1.3'
@@ -203,34 +203,32 @@ module Rails
end
if options[:skip_javascript]
- gemfile += <<-GEMFILE.gsub(/^ {12}/, '')
+ gemfile += <<-GEMFILE
#{coffee_gemfile_entry}
#{javascript_runtime_gemfile_entry}
GEMFILE
end
- gemfile.strip_heredoc.gsub(/^[ \t]*$/, '')
+ gemfile.gsub(/^[ \t]+/, '')
end
def coffee_gemfile_entry
- gemfile = if options.dev? || options.edge?
- <<-GEMFILE.gsub(/^ {12}/, '')
+ if options.dev? || options.edge?
+ <<-GEMFILE
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', github: 'rails/coffee-rails'
GEMFILE
else
- <<-GEMFILE.gsub(/^ {12}/, '')
+ <<-GEMFILE
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0.beta1'
GEMFILE
end
-
- gemfile.strip_heredoc.gsub(/^[ \t]*$/, '')
end
def javascript_gemfile_entry
unless options[:skip_javascript]
- <<-GEMFILE.gsub(/^ {12}/, '').strip_heredoc
+ <<-GEMFILE.gsub(/^[ \t]+/, '')
#{coffee_gemfile_entry}
#{javascript_runtime_gemfile_entry}
# Use #{options[:javascript]} as the JavaScript library
@@ -248,7 +246,7 @@ module Rails
else
"# gem 'therubyracer', platforms: :ruby"
end
- <<-GEMFILE.gsub(/^ {10}/, '')
+ <<-GEMFILE
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
#{runtime}
GEMFILE
diff --git a/railties/test/app_rails_loader_test.rb b/railties/test/app_rails_loader_test.rb
index 0402989705..ceae78ae80 100644
--- a/railties/test/app_rails_loader_test.rb
+++ b/railties/test/app_rails_loader_test.rb
@@ -1,48 +1,68 @@
+require 'tmpdir'
require 'abstract_unit'
require 'rails/app_rails_loader'
class AppRailsLoaderTest < ActiveSupport::TestCase
+ def write(filename, contents=nil)
+ FileUtils.mkdir_p(File.dirname(filename))
+ File.write(filename, contents)
+ end
+
+ def expects_exec(exe)
+ Rails::AppRailsLoader.expects(:exec).with(Rails::AppRailsLoader::RUBY, exe)
+ end
setup do
- File.stubs(:exists?).returns(false)
+ @tmp = Dir.mktmpdir('railties-rails-loader-test-suite')
+ @cwd = Dir.pwd
+ Dir.chdir(@tmp)
end
- ['bin/rails', 'script/rails'].each do |exe|
- test "is in a rails application if #{exe} exists and contains APP_PATH" do
- File.stubs(:exists?).with(exe).returns(true)
- File.stubs(:read).with(exe).returns('APP_PATH')
- assert Rails::AppRailsLoader.find_executable
- end
+ ['bin', 'script'].each do |script_dir|
+ exe = "#{script_dir}/rails"
+
+ test "is not in a Rails application if #{exe} is not found in the current or parent directories" do
+ File.stubs(:exists?).with('bin/rails').returns(false)
+ File.stubs(:exists?).with('script/rails').returns(false)
- test "is not in a rails application if #{exe} exists but doesn't contain APP_PATH" do
- File.stubs(:exists?).with(exe).returns(true)
- File.stubs(:read).with(exe).returns("railties #{exe}")
assert !Rails::AppRailsLoader.exec_app_rails
end
- test "is in a rails application if parent directory has #{exe} containing APP_PATH" do
- File.stubs(:exists?).with("/foo/bar/#{exe}").returns(false)
- File.stubs(:exists?).with("/foo/#{exe}").returns(true)
- File.stubs(:read).with("/foo/#{exe}").returns('APP_PATH')
- assert_equal Rails::AppRailsLoader.find_executable_in_parent_path(Pathname.new("/foo/bar")), "/foo/#{exe}"
- end
+ ['APP_PATH', 'ENGINE_PATH'].each do |keyword|
+ test "is in a Rails application if #{exe} exists and contains #{keyword}" do
+ write exe, keyword
- test "is not in a rails application if at the root directory and doesn't have #{exe}" do
- Pathname.any_instance.stubs(:root?).returns true
- assert !Rails::AppRailsLoader.find_executable
- end
+ expects_exec exe
+ Rails::AppRailsLoader.exec_app_rails
+ end
- test "is in a rails engine if parent directory has #{exe} containing ENGINE_PATH" do
- File.stubs(:exists?).with("/foo/bar/#{exe}").returns(false)
- File.stubs(:exists?).with("/foo/#{exe}").returns(true)
- File.stubs(:read).with("/foo/#{exe}").returns('ENGINE_PATH')
- assert Rails::AppRailsLoader.find_executable_in_parent_path(Pathname.new("/foo/bar")), "/foo/#{exe}"
- end
+ test "is not in a Rails application if #{exe} exists but doesn't contain #{keyword}" do
+ write exe
+
+ assert !Rails::AppRailsLoader.exec_app_rails
+ end
+
+ test "is in a Rails application if parent directory has #{exe} containing #{keyword} and chdirs to the root directory" do
+ write "foo/bar/#{exe}"
+ write "foo/#{exe}", keyword
+
+ Dir.chdir('foo/bar')
- test "is in a rails engine if #{exe} exists containing ENGINE_PATH" do
- File.stubs(:exists?).with(exe).returns(true)
- File.stubs(:read).with(exe).returns('ENGINE_PATH')
- assert Rails::AppRailsLoader.find_executable
+ expects_exec exe
+ Rails::AppRailsLoader.exec_app_rails
+
+ # Compare the realpath in case either of them has symlinks.
+ #
+ # This happens in particular in Mac OS X, where @tmp starts
+ # with "/var", and Dir.pwd with "/private/var", due to a
+ # default system symlink var -> private/var.
+ assert_equal File.realpath("#@tmp/foo"), File.realpath(Dir.pwd)
+ end
end
end
+
+ teardown do
+ Dir.chdir(@cwd)
+ FileUtils.rm_rf(@tmp)
+ end
end
diff --git a/railties/test/application/initializers/load_path_test.rb b/railties/test/application/initializers/load_path_test.rb
index 9b18c329ec..0c66213caa 100644
--- a/railties/test/application/initializers/load_path_test.rb
+++ b/railties/test/application/initializers/load_path_test.rb
@@ -72,6 +72,7 @@ module ApplicationTests
end
test "load environment with global" do
+ $initialize_test_set_from_env = nil
app_file "config/environments/development.rb", <<-RUBY
$initialize_test_set_from_env = 'success'
AppTemplate::Application.configure do
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index eb590da678..fa3ab969ae 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -79,6 +79,23 @@ module ApplicationTests
assert_match "Hello world", output
end
+ def test_should_not_eager_load_model_path_for_rake
+ add_to_config <<-RUBY
+ config.eager_load = true
+
+ rake_tasks do
+ task do_nothing: :environment do
+ end
+ end
+ RUBY
+
+ app_file "app/models/hello.rb", <<-RUBY
+ raise 'should not be pre-required for rake even `eager_load=true`'
+ RUBY
+
+ Dir.chdir(app_path){ `rake do_nothing` }
+ end
+
def test_code_statistics_sanity
assert_match "Code LOC: 5 Test LOC: 0 Code to Test Ratio: 1:0.0",
Dir.chdir(app_path){ `rake stats` }