diff options
23 files changed, 172 insertions, 112 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index b1f0f5fc28..bb6a73afb5 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -181,7 +181,7 @@ module ActionDispatch # to the Message{Encryptor,Verifier} allows us to handle the # (de)serialization step within the cookie jar, which gives us the # opportunity to detect and migrate legacy cookies. - module VerifyAndUpgradeLegacySignedMessage + module VerifyAndUpgradeLegacySignedMessage # :nodoc: def initialize(*args) super @legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token], serializer: ActiveSupport::MessageEncryptor::NullSerializer) @@ -392,7 +392,7 @@ module ActionDispatch end end - class JsonSerializer + class JsonSerializer # :nodoc: def self.load(value) ActiveSupport::JSON.decode(value) end @@ -402,7 +402,7 @@ module ActionDispatch end end - module SerializedCookieJars + module SerializedCookieJars # :nodoc: MARSHAL_SIGNATURE = "\x04\x08".freeze protected @@ -454,12 +454,16 @@ module ActionDispatch @verifier = ActiveSupport::MessageVerifier.new(secret, digest: digest, serializer: ActiveSupport::MessageEncryptor::NullSerializer) end + # Returns the value of the cookie by +name+ if it is untampered, + # returns +nil+ otherwise or if no such cookie exists. def [](name) if signed_message = @parent_jar[name] deserialize name, verify(signed_message) end end + # Signs and sets the cookie named +name+. The second argument may be the cookie's + # value or a hash of options as documented above. def []=(name, options) if options.is_a?(Hash) options.symbolize_keys! @@ -511,12 +515,16 @@ module ActionDispatch @encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, digest: digest, serializer: ActiveSupport::MessageEncryptor::NullSerializer) end + # Returns the value of the cookie by +name+ if it is untampered, + # returns +nil+ otherwise or if no such cookie exists. def [](name) if encrypted_message = @parent_jar[name] deserialize name, decrypt_and_verify(encrypted_message) end end + # Encrypts and sets the cookie named +name+. The second argument may be the cookie's + # value or a hash of options as documented above. def []=(name, options) if options.is_a?(Hash) options.symbolize_keys! diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb index efd790de63..ef30f1ea0f 100644 --- a/actionpack/test/controller/redirect_test.rb +++ b/actionpack/test/controller/redirect_test.rb @@ -1,8 +1,5 @@ require 'abstract_unit' -class WorkshopsController < ActionController::Base -end - class RedirectController < ActionController::Base # empty method not used anywhere to ensure methods like # `status` and `location` aren't called on `redirect_to` calls diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 2d08987ca6..9bbfb74e72 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -8,8 +8,6 @@ class MilestonesController < ActionController::Base alias_method :show, :index end -ROUTING = ActionDispatch::Routing - # See RFC 3986, section 3.3 for allowed path characters. class UriReservedCharactersRoutingTest < ActiveSupport::TestCase include RoutingTestHelpers @@ -871,7 +869,7 @@ class RouteSetTest < ActiveSupport::TestCase def default_route_set @default_route_set ||= begin - set = ROUTING::RouteSet.new + set = ActionDispatch::Routing::RouteSet.new set.draw do get '/:controller(/:action(/:id))' end @@ -1748,13 +1746,13 @@ class RouteSetTest < ActiveSupport::TestCase include ActionDispatch::RoutingVerbs - class TestSet < ROUTING::RouteSet + class TestSet < ActionDispatch::Routing::RouteSet def initialize(block) @block = block super() end - class Dispatcher < ROUTING::RouteSet::Dispatcher + class Dispatcher < ActionDispatch::Routing::RouteSet::Dispatcher def initialize(defaults, set, block) super(defaults) @block = block diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb index 9d7390f1fd..089627a221 100644 --- a/actionview/lib/action_view/helpers/translation_helper.rb +++ b/actionview/lib/action_view/helpers/translation_helper.rb @@ -7,34 +7,47 @@ module ActionView module Helpers module TranslationHelper include TagHelper - # Delegates to <tt>I18n#translate</tt> but also performs three additional functions. + # Delegates to <tt>I18n#translate</tt> but also performs three additional + # functions. # - # First, it will ensure that any thrown +MissingTranslation+ messages will be turned - # into inline spans that: + # First, it will ensure that any thrown +MissingTranslation+ messages will + # be rendered as inline spans that: # - # * have a "translation-missing" class set, - # * contain the missing key as a title attribute and - # * a titleized version of the last key segment as a text. + # * Have a <tt>translation-missing</tt> class applied + # * Contain the missing key as the value of the +title+ attribute + # * Have a titleized version of the last key segment as text # - # E.g. the value returned for a missing translation key :"blog.post.title" will be - # <span class="translation_missing" title="translation missing: en.blog.post.title">Title</span>. - # This way your views will display rather reasonable strings but it will still - # be easy to spot missing translations. + # For example, the value returned for the missing translation key + # <tt>"blog.post.title"</tt> will be: # - # Second, it'll scope the key by the current partial if the key starts - # with a period. So if you call <tt>translate(".foo")</tt> from the - # <tt>people/index.html.erb</tt> template, you'll actually be calling - # <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive - # to translate many keys within the same partials and gives you a simple framework - # for scoping them consistently. If you don't prepend the key with a period, - # nothing is converted. + # <span + # class="translation_missing" + # title="translation missing: en.blog.post.title">Title</span> # - # Third, it'll mark the translation as safe HTML if the key has the suffix - # "_html" or the last element of the key is the word "html". For example, - # calling translate("footer_html") or translate("footer.html") will return - # a safe HTML string that won't be escaped by other HTML helper methods. This - # naming convention helps to identify translations that include HTML tags so that - # you know what kind of output to expect when you call translate in a template. + # This allows for views to display rather reasonable strings while still + # giving developers a way to find missing translations. + # + # If you would prefer missing translations to raise an error, you can + # opt out of span-wrapping behavior globally by setting + # <tt>ActionView::Base.raise_on_missing_translations = true</tt> or + # individually by passing <tt>raise: true</tt> as an option to + # <tt>translate</tt>. + # + # Second, if the key starts with a period <tt>translate</tt> will scope + # the key by the current partial. Calling <tt>translate(".foo")</tt> from + # the <tt>people/index.html.erb</tt> template is equivalent to calling + # <tt>translate("people.index.foo")</tt>. This makes it less + # repetitive to translate many keys within the same partial and provides + # a convention to scope keys consistently. + # + # Third, the translation will be marked as <tt>html_safe</tt> if the key + # has the suffix "_html" or the last element of the key is "html". Calling + # <tt>translate("footer_html")</tt> or <tt>translate("footer.html")</tt> + # will return an HTML safe string that won't be escaped by other HTML + # helper methods. This naming convention helps to identify translations + # that include HTML tags so that you know what kind of output to expect + # when you call translate in a template and translators know which keys + # they can provide HTML values for. def translate(key, options = {}) options = options.dup has_default = options.has_key?(:default) diff --git a/actionview/test/activerecord/form_helper_activerecord_test.rb b/actionview/test/activerecord/form_helper_activerecord_test.rb index 0a62f49f35..2769b97445 100644 --- a/actionview/test/activerecord/form_helper_activerecord_test.rb +++ b/actionview/test/activerecord/form_helper_activerecord_test.rb @@ -35,10 +35,6 @@ class FormHelperActiveRecordTest < ActionView::TestCase end end - def _routes - Routes - end - include Routes.url_helpers def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association diff --git a/actionview/test/template/capture_helper_test.rb b/actionview/test/template/capture_helper_test.rb index f213da5934..1e099d482c 100644 --- a/actionview/test/template/capture_helper_test.rb +++ b/actionview/test/template/capture_helper_test.rb @@ -210,10 +210,4 @@ class CaptureHelperTest < ActionView::TestCase def alt_encoding(output_buffer) output_buffer.encoding == Encoding::US_ASCII ? Encoding::UTF_8 : Encoding::US_ASCII end - - def view_with_controller - TestController.new.view_context.tap do |view| - view.output_buffer = ActionView::OutputBuffer.new - end - end end diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb index a0e1f5f3bb..9212420ec9 100644 --- a/actionview/test/template/date_helper_test.rb +++ b/actionview/test/template/date_helper_test.rb @@ -3217,12 +3217,4 @@ class DateHelperTest < ActionView::TestCase expected = '<time datetime="2013-02-20T00:00:00+00:00">20 Feb 00:00</time>' assert_equal expected, time_tag(time, :format => :short) end - - protected - def with_env_tz(new_tz = 'US/Eastern') - old_tz, ENV['TZ'] = ENV['TZ'], new_tz - yield - ensure - old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ') - end end diff --git a/activejob/lib/active_job/queue_adapters.rb b/activejob/lib/active_job/queue_adapters.rb index 8aa85979f6..bd69e525bb 100644 --- a/activejob/lib/active_job/queue_adapters.rb +++ b/activejob/lib/active_job/queue_adapters.rb @@ -27,7 +27,6 @@ module ActiveJob # | Sneakers | Yes | Yes | No | Queue | Queue | No | # | Sucker Punch | Yes | Yes | No | No | No | No | # | Active Job Inline | No | Yes | N/A | N/A | N/A | N/A | - # | Active Job | Yes | Yes | Yes | No | No | No | # # ==== Async # diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 96be551264..ff7280f9e5 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -23,7 +23,7 @@ module ActiveModel # The requirements to implement <tt>ActiveModel::AttributeMethods</tt> are to: # # * <tt>include ActiveModel::AttributeMethods</tt> in your class. - # * Call each of its method you want to add, such as +attribute_method_suffix+ + # * Call each of its methods you want to add, such as +attribute_method_suffix+ # or +attribute_method_prefix+. # * Call +define_attribute_methods+ after the other methods are called. # * Define the various generic +_attribute+ methods that you have declared. @@ -227,7 +227,7 @@ module ActiveModel # Declares the attributes that should be prefixed and suffixed by # ActiveModel::AttributeMethods. # - # To use, pass attribute names (as strings or symbols), be sure to declare + # To use, pass attribute names (as strings or symbols). Be sure to declare # +define_attribute_methods+ after you define any prefix, suffix or affix # methods, or they will not hook in. # @@ -239,7 +239,7 @@ module ActiveModel # # # Call to define_attribute_methods must appear after the # # attribute_method_prefix, attribute_method_suffix or - # # attribute_method_affix declares. + # # attribute_method_affix declarations. # define_attribute_methods :name, :age, :address # # private @@ -255,7 +255,7 @@ module ActiveModel # Declares an attribute that should be prefixed and suffixed by # ActiveModel::AttributeMethods. # - # To use, pass an attribute name (as string or symbol), be sure to declare + # To use, pass an attribute name (as string or symbol). Be sure to declare # +define_attribute_method+ after you define any prefix, suffix or affix # method, or they will not hook in. # @@ -267,7 +267,7 @@ module ActiveModel # # # Call to define_attribute_method must appear after the # # attribute_method_prefix, attribute_method_suffix or - # # attribute_method_affix declares. + # # attribute_method_affix declarations. # define_attribute_method :name # # private @@ -363,7 +363,7 @@ module ActiveModel end # Define a method `name` in `mod` that dispatches to `send` - # using the given `extra` args. This fallbacks `define_method` + # using the given `extra` args. This falls back on `define_method` # and `send` if the given names cannot be compiled. def define_proxy_call(include_private, mod, name, send, *extra) #:nodoc: defn = if name =~ NAME_COMPILABLE_REGEXP @@ -419,7 +419,7 @@ module ActiveModel # returned by <tt>attributes</tt>, as though they were first-class # methods. So a +Person+ class with a +name+ attribute can for example use # <tt>Person#name</tt> and <tt>Person#name=</tt> and never directly use - # the attributes hash -- except for multiple assigns with + # the attributes hash -- except for multiple assignments with # <tt>ActiveRecord::Base#attributes=</tt>. # # It's also possible to instantiate related objects, so a <tt>Client</tt> diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 319ccaec3a..d30c8e345f 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,11 @@ +* Fix missing index when using `timestamps` with the `index` option. + + The `index` option used with `timestamps` should be passed to both + `column` definitions for `created_at` and `updated_at` rather than just + the first. + + *Paul Mucur* + * Rename `:class` to `:anonymous_class` in association options. Fixes #19659. diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index cb83d0022c..4761024ad0 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -359,6 +359,7 @@ module ActiveRecord def column(name, type, options = {}) name = name.to_s type = type.to_sym + options = options.dup if @columns_hash[name] && @columns_hash[name].primary_key? raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table." diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index ecb4868c13..879a47f021 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -120,6 +120,8 @@ module ActiveRecord # [<tt>:id</tt>] # Whether to automatically add a primary key column. Defaults to true. # Join tables for +has_and_belongs_to_many+ should set it to false. + # + # A Symbol can be used to specify the type of the generated primary key column. # [<tt>:primary_key</tt>] # The name of the primary key, if one is to be added automatically. # Defaults to +id+. If <tt>:id</tt> is false this option is ignored. @@ -163,6 +165,19 @@ module ActiveRecord # name varchar(80) # ) # + # ====== Change the primary key column type + # + # create_table(:tags, id: :string) do |t| + # t.column :label, :string + # end + # + # generates: + # + # CREATE TABLE tags ( + # id varchar PRIMARY KEY, + # label varchar + # ) + # # ====== Do not add a primary key column # # create_table(:categories_suppliers, id: false) do |t| diff --git a/activerecord/test/cases/disconnected_test.rb b/activerecord/test/cases/disconnected_test.rb index 55f0e51717..c25089a420 100644 --- a/activerecord/test/cases/disconnected_test.rb +++ b/activerecord/test/cases/disconnected_test.rb @@ -21,7 +21,9 @@ class TestDisconnectedAdapter < ActiveRecord::TestCase @connection.execute "SELECT count(*) from products" @connection.disconnect! assert_raises(ActiveRecord::StatementInvalid) do - @connection.execute "SELECT count(*) from products" + silence_warnings do + @connection.execute "SELECT count(*) from products" + end end end end diff --git a/activerecord/test/cases/timestamp_test.rb b/activerecord/test/cases/timestamp_test.rb index 7c89b4b9e8..5dab32995c 100644 --- a/activerecord/test/cases/timestamp_test.rb +++ b/activerecord/test/cases/timestamp_test.rb @@ -446,6 +446,17 @@ class TimestampTest < ActiveRecord::TestCase toy = Toy.first assert_equal [:created_at, :updated_at], toy.send(:all_timestamp_attributes_in_model) end + + def test_index_is_created_for_both_timestamps + ActiveRecord::Base.connection.create_table(:foos, force: true) do |t| + t.timestamps(:foos, null: true, index: true) + end + + indexes = ActiveRecord::Base.connection.indexes('foos') + assert_equal ['created_at', 'updated_at'], indexes.flat_map(&:columns).sort + ensure + ActiveRecord::Base.connection.drop_table(:foos) + end end class TimestampsWithoutTransactionTest < ActiveRecord::TestCase diff --git a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb index a03a66b96b..dedcdfdb60 100644 --- a/activesupport/lib/active_support/deprecation/proxy_wrappers.rb +++ b/activesupport/lib/active_support/deprecation/proxy_wrappers.rb @@ -25,15 +25,17 @@ module ActiveSupport end end - # This DeprecatedObjectProxy transforms object to deprecated object. + # DeprecatedObjectProxy transforms an object into a deprecated object. It takes an object, + # a deprecation message, and optionally a deprecator. The deprecator defaults to + # <tt>ActiveSupport::Deprecator</tt> if none is specified. # - # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!") - # @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!", deprecator_instance) + # deprecated_object = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(Object.new, "This object is now deprecated") + # # => <Object:0x007fb9b34c34b0> # - # When someone executes any method except +inspect+ on proxy object this will - # trigger +warn+ method on +deprecator_instance+. - # - # Default deprecator is <tt>ActiveSupport::Deprecation</tt> + # deprecated_object.to_s + # DEPRECATION WARNING: This object is now deprecated. + # (Backtrace) + # # => "<Object:0x007fb9b34c34b0>" class DeprecatedObjectProxy < DeprecationProxy def initialize(object, message, deprecator = ActiveSupport::Deprecation.instance) @object = object @@ -51,13 +53,15 @@ module ActiveSupport end end - # This DeprecatedInstanceVariableProxy transforms instance variable to - # deprecated instance variable. + # DeprecatedInstanceVariableProxy transforms an instance variable into a deprecated + # instance variable. It takes an instance of a class, a method on that class, and an + # instance variable. It optionally takes a deprecator as the last argument. The deprecator + # defaults to <tt>ActiveSupport::Deprecator</tt> if none is specified. # # class Example - # def initialize(deprecator) + # def initialize # @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator) - # @_request = :a_request + # @_request = :special_request # end # # def request @@ -69,12 +73,17 @@ module ActiveSupport # end # end # - # When someone execute any method on @request variable this will trigger - # +warn+ method on +deprecator_instance+ and will fetch <tt>@_request</tt> - # variable via +request+ method and execute the same method on non-proxy - # instance variable. + # example = Example.new + # # => #<Example:0x007fb9b31090b8 @_request=:special_request, @request=:special_request> + # + # example.old_request.to_s + # # => DEPRECATION WARNING: @request is deprecated! Call request.to_s instead of + # @request.to_s + # (Bactrace information…) + # "special_request" # - # Default deprecator is <tt>ActiveSupport::Deprecation</tt>. + # example.request.to_s + # # => "special_request" class DeprecatedInstanceVariableProxy < DeprecationProxy def initialize(instance, method, var = "@#{method}", deprecator = ActiveSupport::Deprecation.instance) @instance = instance @@ -93,15 +102,22 @@ module ActiveSupport end end - # This DeprecatedConstantProxy transforms constant to deprecated constant. + # DeprecatedConstantProxy transforms a constant into a deprecated constant. It takes the names of an old + # (deprecated) constant and a new contstant (both in string form), and optionally a deprecator. The + # deprecator defaults to <tt>ActiveSupport::Deprecator</tt> if none is specified. The deprecated constant + # now returns the return value of the new constant. + # + # PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto) # - # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST') - # OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST', deprecator_instance) + # (In a later update, the orignal implementation of `PLANETS` has been removed.) # - # When someone use old constant this will trigger +warn+ method on - # +deprecator_instance+. + # PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune) + # PLANETS = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('PLANETS', 'PLANETS_POST_2006') # - # Default deprecator is <tt>ActiveSupport::Deprecation</tt>. + # PLANETS.map { |planet| planet.capitalize } + # # => DEPRECATION WARNING: PLANETS is deprecated! Use PLANETS_POST_2006 instead. + # (Bactrace information…) + # ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"] class DeprecatedConstantProxy < DeprecationProxy def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance) @old_const = old_const diff --git a/activesupport/lib/active_support/subscriber.rb b/activesupport/lib/active_support/subscriber.rb index 8db423f0e9..1cd4b807ad 100644 --- a/activesupport/lib/active_support/subscriber.rb +++ b/activesupport/lib/active_support/subscriber.rb @@ -5,7 +5,7 @@ module ActiveSupport # 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 + # An example would be an Active Record subscriber responsible for collecting # statistics about queries: # # module ActiveRecord @@ -61,7 +61,7 @@ module ActiveSupport pattern = "#{event}.#{namespace}" - # don't add multiple subscribers (eg. if methods are redefined) + # Don't add multiple subscribers (eg. if methods are redefined). return if subscriber.patterns.include?(pattern) subscriber.patterns << pattern diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md index 44c02165db..f0ff3d8864 100644 --- a/guides/source/action_view_overview.md +++ b/guides/source/action_view_overview.md @@ -356,39 +356,34 @@ Supposing we use the same `_box` partial from above, this would produce the same View Paths ---------- -When rendering the view for a request, the controller needs to resolve where to find each of the directories are located. +When rendering a response, the controller needs to resolve where the different +views are located. By default it only looks inside the `app/views` directory. -We are able to modify the order these locations are resolved by using `prepend_view_path` and `append_view_path`. - -This allows us to add new paths to the beginning or end of the list used to resolve these paths. +We can add other locations and give them a certain precedence when resolving +paths using the `prepend_view_path` and `append_view_path` methods. ### Prepend view path -This can be helpful for example, when we want to prepend a different directory for subdomains. +This can be helpful for example, when we want to put views inside a different +directory for subdomains. We can do this by using: -```prepend_view_path "app/views/#{request.subdomain}"``` - -Then our list becomes something like: - -``` -[ - ~/rails_app/app/views/<subdomain>, - ~/rails_app/app/views, - # ... -] +```ruby +prepend_view_path "app/views/#{request.subdomain}" ``` -This will put the subdomain path at the beginning of the list. +Then Action View will look first in this directory when resolving views. ### Append view path Similarly, we can append paths: -```append_view_path "app/views/direct"```. +```ruby +append_view_path "app/views/direct" +``` -This will add ```app/views/direct``` and the end of lookup paths for views. +This will add `app/views/direct` to the end of the lookup paths. Overview of helpers provided by Action View ------------------------------------------- diff --git a/guides/source/configuring.md b/guides/source/configuring.md index aa66376d5d..938ba2c89f 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -114,7 +114,7 @@ numbers. New applications filter out passwords by adding the following `config.f defaults to `:debug` for all environments. The available log levels are: `:debug`, `:info`, `:warn`, `:error`, `:fatal`, and `:unknown`. -* `config.log_tags` accepts a list of methods that the `request` object responds to. This makes it easy to tag log lines with debug information like subdomain and request id - both very helpful in debugging multi-user production applications. +* `config.log_tags` accepts a list of: methods that the `request` object responds to, a `Proc` that accepts the `request` object, or something that responds to `to_s`. This makes it easy to tag log lines with debug information like subdomain and request id - both very helpful in debugging multi-user production applications. * `config.logger` accepts a logger conforming to the interface of Log4r or the default Ruby `Logger` class. Defaults to an instance of `ActiveSupport::Logger`. diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb index 6c583e5811..0a4c509a31 100644 --- a/railties/lib/rails/generators/rails/controller/controller_generator.rb +++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb @@ -19,7 +19,8 @@ module Rails end end - hook_for :template_engine, :test_framework, :helper, :assets + hook_for :template_engine, :test_framework + hook_for :helper, :assets, hide: true private diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb index 9962e6d943..7aaa353b91 100644 --- a/railties/lib/rails/rack/logger.rb +++ b/railties/lib/rails/rack/logger.rb @@ -7,6 +7,9 @@ require 'rack/body_proxy' module Rails module Rack # Sets log tags, logs the request, calls the app, and flushes the logs. + # + # Log tags (+taggers+) can be an Array containing: methods that the <tt>request</tt> object responds to, a Proc + # that accepts an instance of the <tt>request</tt> object, or something that responds to <tt>to_s</tt>. class Logger < ActiveSupport::LogSubscriber def initialize(app, taggers = nil) @app = app diff --git a/railties/lib/rails/templates/rails/welcome/index.html.erb b/railties/lib/rails/templates/rails/welcome/index.html.erb index 6726c23fc9..acf04af416 100644 --- a/railties/lib/rails/templates/rails/welcome/index.html.erb +++ b/railties/lib/rails/templates/rails/welcome/index.html.erb @@ -18,7 +18,9 @@ color: #000; } - a {color: #03c} + a { + color: #03c; + } a:hover { background-color: #03c; @@ -64,7 +66,10 @@ height: 64px; } - #header h1, #header h2 {margin: 0} + #header h1, + #header h2 { + margin: 0; + } #header h2 { color: #888; @@ -104,7 +109,9 @@ color: #555; } - #about-content td.value {color: #000} + #about-content td.value { + color: #000; + } #about-content ul { padding: 0; diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb index 127e059bf1..fdcfb30090 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -34,6 +34,12 @@ class GeneratorsTest < Rails::Generators::TestCase assert_match "Maybe you meant 'migration'", output end + def test_generator_multiple_suggestions + name = :tas + output = capture(:stdout){ Rails::Generators.invoke name } + assert_match "Maybe you meant 'task', 'job' or 'assets'", output + end + def test_help_when_a_generator_with_required_arguments_is_invoked_without_arguments output = capture(:stdout){ Rails::Generators.invoke :model, [] } assert_match(/Description:/, output) diff --git a/railties/test/path_generation_test.rb b/railties/test/path_generation_test.rb index e3dfcdfb7d..d22374a1ff 100644 --- a/railties/test/path_generation_test.rb +++ b/railties/test/path_generation_test.rb @@ -4,18 +4,16 @@ require 'active_support/core_ext/object/json' require 'rails' require 'rails/application' -ROUTING = ActionDispatch::Routing - class PathGenerationTest < ActiveSupport::TestCase attr_reader :app - class TestSet < ROUTING::RouteSet + class TestSet < ActionDispatch::Routing::RouteSet def initialize(block) @block = block super() end - class Dispatcher < ROUTING::RouteSet::Dispatcher + class Dispatcher < ActionDispatch::Routing::RouteSet::Dispatcher def initialize(defaults, set, block) super(defaults) @block = block |