diff options
68 files changed, 443 insertions, 316 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index c6ea22a591..96af4d9397 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,7 @@ +* Make `fixture_file_upload` work in integration tests. + + *Yuji Yaginuma* + * Add `to_param` to `ActionController::Parameters` deprecations. In the future `ActionController::Parameters` are discouraged from being used diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb index a26ebd2b24..89bf60a0bb 100644 --- a/actionpack/lib/action_controller/metal/conditional_get.rb +++ b/actionpack/lib/action_controller/metal/conditional_get.rb @@ -242,8 +242,9 @@ module ActionController response.date = Time.now unless response.date? end - # Sets an HTTP 1.1 Cache-Control header of <tt>no-cache</tt> so no caching should - # occur by the browser or intermediate caches (like caching proxy servers). + # Sets an HTTP 1.1 Cache-Control header of <tt>no-cache</tt>. This means the + # resource will be marked as stale, so clients must always revalidate. + # Intermediate/browser caches may still store the asset. def expires_now response.cache_control.replace(no_cache: true) end diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index dea4657988..387c2aa0b9 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -578,7 +578,7 @@ module ActionController # +other_hash+ merges into current hash. def merge(other_hash) new_instance_with_inherited_permitted_status( - @parameters.merge(other_hash) + @parameters.merge(other_hash.to_h) ) end diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index d84320b713..16ddd3b304 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -663,14 +663,14 @@ module ActionController def non_kwarg_request_warning ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc) - ActionController::TestCase HTTP request methods will accept only - keyword arguments in future Rails versions. + ActionController::TestCase HTTP request methods will accept only + keyword arguments in future Rails versions. - Examples: + Examples: - get :show, params: { id: 1 }, session: { user_id: 1 } - process :update, method: :post, params: { id: 1 } - MSG + get :show, params: { id: 1 }, session: { user_id: 1 } + process :update, method: :post, params: { id: 1 } + MSG end def document_root_element diff --git a/actionpack/lib/action_dispatch/journey/nfa/dot.rb b/actionpack/lib/action_dispatch/journey/nfa/dot.rb index 0cd71b726a..8119e5d9da 100644 --- a/actionpack/lib/action_dispatch/journey/nfa/dot.rb +++ b/actionpack/lib/action_dispatch/journey/nfa/dot.rb @@ -26,7 +26,7 @@ digraph nfa { node [shape = circle]; #{edges.join "\n"} } - eodot + eodot end end end diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index e49bf54115..466eb8b3f1 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -119,7 +119,7 @@ them to actual class references. For example: "#{klass}" => #{converted_klass} - eowarn + eowarn converted_klass else klass diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 0082b3d8cb..720651fa1f 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -179,7 +179,7 @@ module ActionDispatch DEFAULT_HOST = "www.example.com" include Minitest::Assertions - include TestProcess, RequestHelpers, Assertions + include RequestHelpers, Assertions %w( status status_message headers body redirect? ).each do |method| delegate method, to: :response, allow_nil: true @@ -711,6 +711,8 @@ module ActionDispatch # Consult the Rails Testing Guide for more. class IntegrationTest < ActiveSupport::TestCase + include TestProcess + module UrlOptions extend ActiveSupport::Concern def url_options diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 9044eff801..d3bc77d3ef 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -1281,3 +1281,39 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest end end end + +class IntegrationFileUploadTest < ActionDispatch::IntegrationTest + class IntegrationController < ActionController::Base + def test_file_upload + render plain: params[:file].size + end + end + + def self.routes + @routes ||= ActionDispatch::Routing::RouteSet.new + end + + def self.call(env) + routes.call(env) + end + + def app + self.class + end + + def self.fixture_path + File.dirname(__FILE__) + "/../fixtures/multipart" + end + + routes.draw do + post "test_file_upload", to: "integration_file_upload_test/integration#test_file_upload" + end + + def test_fixture_file_upload + post "/test_file_upload", + params: { + file: fixture_file_upload("/mona_lisa.jpg", "image/jpg") + } + assert_equal "159528", @response.body + end +end diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index 164efd936c..728d8e1279 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -237,6 +237,13 @@ class ParametersPermitTest < ActiveSupport::TestCase assert @params.merge(a: "b").permitted? end + test "merge with parameters" do + other_params = ActionController::Parameters.new(id: "1234").permit! + merged_params = @params.merge(other_params) + + assert merged_params[:id] + end + test "modifying the parameters" do @params[:person][:hometown] = "Chicago" @params[:person][:family] = { brother: "Jonas" } diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index eec34dba66..6ba52e37b6 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -3693,7 +3693,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal "admin/pages#index", @response.body end - def test_namespaced_roots + def test_multiple_namespaced_roots draw do namespace :foo do root "test#index" diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb index c277738920..61ce1d36e0 100644 --- a/actionview/lib/action_view/helpers/date_helper.rb +++ b/actionview/lib/action_view/helpers/date_helper.rb @@ -1026,15 +1026,16 @@ module ActionView # prompt_option_tag(:month, prompt: 'Select month') # => "<option value="">Select month</option>" def prompt_option_tag(type, options) - prompt = case options - when Hash - default_options = { year: false, month: false, day: false, hour: false, minute: false, second: false } - default_options.merge!(options)[type.to_sym] - when String - options + prompt = \ + case options + when Hash + default_options = { year: false, month: false, day: false, hour: false, minute: false, second: false } + default_options.merge!(options)[type.to_sym] + when String + options else - I18n.translate(:"datetime.prompts.#{type}", locale: @options[:locale]) - end + I18n.translate(:"datetime.prompts.#{type}", locale: @options[:locale]) + end prompt ? content_tag("option".freeze, prompt, value: "") : "" end diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb index a8abe6b7c4..7bd473507b 100644 --- a/actionview/lib/action_view/helpers/form_tag_helper.rb +++ b/actionview/lib/action_view/helpers/form_tag_helper.rb @@ -857,23 +857,24 @@ module ActionView authenticity_token = html_options.delete("authenticity_token") method = html_options.delete("method").to_s.downcase - method_tag = case method - when "get" - html_options["method"] = "get" - "" - when "post", "" - html_options["method"] = "post" - token_tag(authenticity_token, form_options: { - action: html_options["action"], - method: "post" - }) + method_tag = \ + case method + when "get" + html_options["method"] = "get" + "" + when "post", "" + html_options["method"] = "post" + token_tag(authenticity_token, form_options: { + action: html_options["action"], + method: "post" + }) else - html_options["method"] = "post" - method_tag(method) + token_tag(authenticity_token, form_options: { - action: html_options["action"], - method: method - }) - end + html_options["method"] = "post" + method_tag(method) + token_tag(authenticity_token, form_options: { + action: html_options["action"], + method: method + }) + end if html_options.delete("enforce_utf8") { true } utf8_enforcer_tag + method_tag diff --git a/actionview/lib/action_view/layouts.rb b/actionview/lib/action_view/layouts.rb index b6bf6b9374..dd5f6e7300 100644 --- a/actionview/lib/action_view/layouts.rb +++ b/actionview/lib/action_view/layouts.rb @@ -290,11 +290,12 @@ module ActionView RUBY end - layout_definition = case _layout - when String - _layout.inspect - when Symbol - <<-RUBY + layout_definition = \ + case _layout + when String + _layout.inspect + when Symbol + <<-RUBY #{_layout}.tap do |layout| return #{default_behavior} if layout.nil? unless layout.is_a?(String) || !layout @@ -303,21 +304,21 @@ module ActionView end end RUBY - when Proc - define_method :_layout_from_proc, &_layout - protected :_layout_from_proc - <<-RUBY + when Proc + define_method :_layout_from_proc, &_layout + protected :_layout_from_proc + <<-RUBY result = _layout_from_proc(#{_layout.arity == 0 ? '' : 'self'}) return #{default_behavior} if result.nil? result RUBY - when false - nil - when true - raise ArgumentError, "Layouts must be specified as a String, Symbol, Proc, false, or nil" - when nil - name_clause - end + when false + nil + when true + raise ArgumentError, "Layouts must be specified as a String, Symbol, Proc, false, or nil" + when nil + name_clause + end self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout(formats) diff --git a/activejob/lib/active_job/test_helper.rb b/activejob/lib/active_job/test_helper.rb index 35fee7452c..bbd2a0c06c 100644 --- a/activejob/lib/active_job/test_helper.rb +++ b/activejob/lib/active_job/test_helper.rb @@ -11,7 +11,7 @@ module ActiveJob def before_setup # :nodoc: test_adapter = queue_adapter_for_test - @old_queue_adapters = (ActiveJob::Base.subclasses << ActiveJob::Base).select do |klass| + @old_queue_adapters = (ActiveJob::Base.descendants << ActiveJob::Base).select do |klass| # only override explicitly set adapters, a quirk of `class_attribute` klass.singleton_class.public_instance_methods(false).include?(:_queue_adapter) end.map do |klass| diff --git a/activejob/test/cases/test_helper_test.rb b/activejob/test/cases/test_helper_test.rb index 2398402d5d..253c557cc5 100644 --- a/activejob/test/cases/test_helper_test.rb +++ b/activejob/test/cases/test_helper_test.rb @@ -5,6 +5,7 @@ require "jobs/hello_job" require "jobs/logging_job" require "jobs/nested_job" require "jobs/rescue_job" +require "jobs/inherited_job" require "models/person" class EnqueuedJobsTest < ActiveJob::TestCase @@ -521,3 +522,9 @@ class OverrideQueueAdapterTest < ActiveJob::TestCase assert_instance_of CustomQueueAdapter, HelloJob.queue_adapter end end + +class InheritedJobTest < ActiveJob::TestCase + def test_queue_adapter_is_test_adapter + assert_instance_of ActiveJob::QueueAdapters::TestAdapter, InheritedJob.queue_adapter + end +end diff --git a/activejob/test/jobs/application_job.rb b/activejob/test/jobs/application_job.rb new file mode 100644 index 0000000000..4a78b890ec --- /dev/null +++ b/activejob/test/jobs/application_job.rb @@ -0,0 +1,4 @@ +require_relative "../support/job_buffer" + +class ApplicationJob < ActiveJob::Base +end diff --git a/activejob/test/jobs/inherited_job.rb b/activejob/test/jobs/inherited_job.rb new file mode 100644 index 0000000000..60fca66f88 --- /dev/null +++ b/activejob/test/jobs/inherited_job.rb @@ -0,0 +1,5 @@ +require_relative "application_job" + +class InheritedJob < ApplicationJob + self.queue_adapter = :inline +end diff --git a/activemodel/lib/active_model/type/decimal.rb b/activemodel/lib/active_model/type/decimal.rb index 6266933636..6c5c0451c6 100644 --- a/activemodel/lib/active_model/type/decimal.rb +++ b/activemodel/lib/active_model/type/decimal.rb @@ -16,18 +16,19 @@ module ActiveModel private def cast_value(value) - casted_value = case value - when ::Float - convert_float_to_big_decimal(value) - when ::Numeric, ::String - BigDecimal(value, precision.to_i) - else - if value.respond_to?(:to_d) - value.to_d - else - cast_value(value.to_s) - end - end + casted_value = \ + case value + when ::Float + convert_float_to_big_decimal(value) + when ::Numeric, ::String + BigDecimal(value, precision.to_i) + else + if value.respond_to?(:to_d) + value.to_d + else + cast_value(value.to_s) + end + end apply_scale(casted_value) end diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 7759b0a044..dc6fe1640e 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1810,12 +1810,12 @@ module ActiveRecord include Module.new { class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def destroy_associations - association(:#{middle_reflection.name}).delete_all(:delete_all) - association(:#{name}).reset - super - end - RUBY + def destroy_associations + association(:#{middle_reflection.name}).delete_all(:delete_all) + association(:#{name}).reset + super + end + RUBY } hm_options = {} diff --git a/activerecord/lib/active_record/associations/association.rb b/activerecord/lib/active_record/associations/association.rb index 8328286805..f506614591 100644 --- a/activerecord/lib/active_record/associations/association.rb +++ b/activerecord/lib/active_record/associations/association.rb @@ -173,6 +173,14 @@ module ActiveRecord set_inverse_instance(record) end + def create(attributes = {}, &block) + _create_record(attributes, &block) + end + + def create!(attributes = {}, &block) + _create_record(attributes, true, &block) + end + private def find_target? diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index 0c911a5396..08bd532fb0 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -113,14 +113,6 @@ module ActiveRecord end end - def create(attributes = {}, &block) - _create_record(attributes, &block) - end - - def create!(attributes = {}, &block) - _create_record(attributes, true, &block) - end - # Add +records+ to this association. Returns +self+ so method calls may # be chained. Since << flattens its argument list and inserts each record, # +push+ and +concat+ behave identically. @@ -191,31 +183,6 @@ module ActiveRecord end end - # Returns the number of records. If no arguments are given, it counts all - # columns using SQL. If one argument is given, it counts only the passed - # column using SQL. If a block is given, it counts the number of records - # yielding a true value. - def count(column_name = nil) - return super if block_given? - relation = scope - if association_scope.distinct_value - # This is needed because 'SELECT count(DISTINCT *)..' is not valid SQL. - column_name ||= reflection.klass.primary_key - relation = relation.distinct - end - - value = relation.count(column_name) - - limit = options[:limit] - offset = options[:offset] - - if limit || offset - [ [value - offset.to_i, 0].max, limit.to_i ].min - else - value - end - end - # Removes +records+ from this association calling +before_remove+ and # +after_remove+ callbacks. # @@ -260,9 +227,9 @@ module ActiveRecord else target.size end - elsif !loaded? && !association_scope.group_values.empty? + elsif !association_scope.group_values.empty? load_target.size - elsif !loaded? && !association_scope.distinct_value && target.is_a?(Array) + elsif !association_scope.distinct_value && target.is_a?(Array) unsaved_records = target.select(&:new_record?) unsaved_records.size + count_records else diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb index 48436155ce..dda240585e 100644 --- a/activerecord/lib/active_record/associations/collection_proxy.rb +++ b/activerecord/lib/active_record/associations/collection_proxy.rb @@ -743,6 +743,20 @@ module ActiveRecord end alias uniq distinct + def calculate(operation, column_name) + null_scope? ? scope.calculate(operation, column_name) : super + end + + def pluck(*column_names) + null_scope? ? scope.pluck(*column_names) : super + end + + ## + # :method: count + # + # :call-seq: + # count(column_name = nil, &block) + # # Count all records. # # class Person < ActiveRecord::Base @@ -762,17 +776,6 @@ module ActiveRecord # perform the count using Ruby. # # person.pets.count { |pet| pet.name.include?('-') } # => 2 - def count(column_name = nil, &block) - @association.count(column_name, &block) - end - - def calculate(operation, column_name) - null_scope? ? scope.calculate(operation, column_name) : super - end - - def pluck(*column_names) - null_scope? ? scope.pluck(*column_names) : super - end # Returns the size of the collection. If the collection hasn't been loaded, # it executes a <tt>SELECT COUNT(*)</tt> query. Else it calls <tt>collection.size</tt>. diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb index 07407700cd..c79efca920 100644 --- a/activerecord/lib/active_record/associations/preloader/association.rb +++ b/activerecord/lib/active_record/associations/preloader/association.rb @@ -28,10 +28,6 @@ module ActiveRecord end def records_for(ids) - query_scope(ids) - end - - def query_scope(ids) scope.where(association_key_name => ids) end diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb index 1fe9a23263..483a9df740 100644 --- a/activerecord/lib/active_record/associations/singular_association.rb +++ b/activerecord/lib/active_record/associations/singular_association.rb @@ -23,14 +23,6 @@ module ActiveRecord replace(record) end - def create(attributes = {}, &block) - _create_record(attributes, &block) - end - - def create!(attributes = {}, &block) - _create_record(attributes, true, &block) - end - def build(attributes = {}) record = build_record(attributes) yield(record) if block_given? diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb index 9e99ed8ac1..6243398a52 100644 --- a/activerecord/lib/active_record/attribute_methods/primary_key.rb +++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb @@ -130,10 +130,10 @@ module ActiveRecord return pk unless pk.is_a?(Array) warn <<-WARNING.strip_heredoc - WARNING: Active Record does not support composite primary key. + WARNING: Active Record does not support composite primary key. - #{table_name} has composite primary key. Composite primary key is ignored. - WARNING + #{table_name} has composite primary key. Composite primary key is ignored. + WARNING end end end diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb index 58f82cfd30..131ed8740b 100644 --- a/activerecord/lib/active_record/attribute_methods/read.rb +++ b/activerecord/lib/active_record/attribute_methods/read.rb @@ -31,11 +31,11 @@ module ActiveRecord ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 - def #{temp_method} - name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name} - _read_attribute(name) { |n| missing_attribute(n, caller) } - end - STR + def #{temp_method} + name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name} + _read_attribute(name) { |n| missing_attribute(n, caller) } + end + STR generated_attribute_methods.module_eval do alias_method name, temp_method diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb index 2c8e86fbb2..bea1514cdf 100644 --- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb +++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb @@ -94,18 +94,18 @@ module ActiveRecord cast_type.type == :time && time_zone_aware_types.include?(:not_explicitly_configured) ActiveSupport::Deprecation.warn(<<-MESSAGE.strip_heredoc) - Time columns will become time zone aware in Rails 5.1. This - still causes `String`s to be parsed as if they were in `Time.zone`, - and `Time`s to be converted to `Time.zone`. + Time columns will become time zone aware in Rails 5.1. This + still causes `String`s to be parsed as if they were in `Time.zone`, + and `Time`s to be converted to `Time.zone`. - To keep the old behavior, you must add the following to your initializer: + To keep the old behavior, you must add the following to your initializer: - config.active_record.time_zone_aware_types = [:datetime] + config.active_record.time_zone_aware_types = [:datetime] - To silence this deprecation warning, add the following: + To silence this deprecation warning, add the following: - config.active_record.time_zone_aware_types = [:datetime, :time] - MESSAGE + config.active_record.time_zone_aware_types = [:datetime, :time] + MESSAGE end result diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb index 5822414129..e9d044ef13 100644 --- a/activerecord/lib/active_record/attribute_methods/write.rb +++ b/activerecord/lib/active_record/attribute_methods/write.rb @@ -15,13 +15,13 @@ module ActiveRecord ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1 - def __temp__#{safe_name}=(value) - name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name} - write_attribute(name, value) - end - alias_method #{(name + '=').inspect}, :__temp__#{safe_name}= - undef_method :__temp__#{safe_name}= - STR + def __temp__#{safe_name}=(value) + name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name} + write_attribute(name, value) + end + alias_method #{(name + '=').inspect}, :__temp__#{safe_name}= + undef_method :__temp__#{safe_name}= + STR end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index 4333cd1f57..d0ea1ce0cf 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -570,22 +570,23 @@ module ActiveRecord # Maps logical Rails types to MySQL-specific data types. def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = nil) - sql = case type.to_s - when "integer" - integer_to_sql(limit) - when "text" - text_to_sql(limit) - when "blob" - binary_to_sql(limit) - when "binary" - if (0..0xfff) === limit - "varbinary(#{limit})" - else - binary_to_sql(limit) - end - else - super(type, limit, precision, scale) - end + sql = \ + case type.to_s + when "integer" + integer_to_sql(limit) + when "text" + text_to_sql(limit) + when "blob" + binary_to_sql(limit) + when "binary" + if (0..0xfff) === limit + "varbinary(#{limit})" + else + binary_to_sql(limit) + end + else + super(type, limit, precision, scale) + end sql << " unsigned" if unsigned && type != :primary_key sql diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index 6f5d46b406..29a77580f5 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -625,31 +625,32 @@ module ActiveRecord # Maps logical Rails types to PostgreSQL-specific data types. def type_to_sql(type, limit = nil, precision = nil, scale = nil, array = nil) - sql = case type.to_s - when "binary" - # PostgreSQL doesn't support limits on binary (bytea) columns. - # The hard limit is 1GB, because of a 32-bit size field, and TOAST. - case limit - when nil, 0..0x3fffffff; super(type) - else raise(ActiveRecordError, "No binary type has byte size #{limit}.") - end - when "text" - # PostgreSQL doesn't support limits on text columns. - # The hard limit is 1GB, according to section 8.3 in the manual. - case limit - when nil, 0..0x3fffffff; super(type) - else raise(ActiveRecordError, "The limit on text can be at most 1GB - 1byte.") - end - when "integer" - case limit - when 1, 2; "smallint" - when nil, 3, 4; "integer" - when 5..8; "bigint" - else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with scale 0 instead.") - end - else - super(type, limit, precision, scale) - end + sql = \ + case type.to_s + when "binary" + # PostgreSQL doesn't support limits on binary (bytea) columns. + # The hard limit is 1GB, because of a 32-bit size field, and TOAST. + case limit + when nil, 0..0x3fffffff; super(type) + else raise(ActiveRecordError, "No binary type has byte size #{limit}.") + end + when "text" + # PostgreSQL doesn't support limits on text columns. + # The hard limit is 1GB, according to section 8.3 in the manual. + case limit + when nil, 0..0x3fffffff; super(type) + else raise(ActiveRecordError, "The limit on text can be at most 1GB - 1byte.") + end + when "integer" + case limit + when 1, 2; "smallint" + when nil, 3, 4; "integer" + when 5..8; "bigint" + else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with scale 0 instead.") + end + else + super(type, limit, precision, scale) + end sql << "[]" if array && type != :primary_key sql diff --git a/activerecord/lib/active_record/dynamic_matchers.rb b/activerecord/lib/active_record/dynamic_matchers.rb index 55490e27bc..bbd8ca2377 100644 --- a/activerecord/lib/active_record/dynamic_matchers.rb +++ b/activerecord/lib/active_record/dynamic_matchers.rb @@ -63,10 +63,10 @@ module ActiveRecord def define model.class_eval <<-CODE, __FILE__, __LINE__ + 1 - def self.#{name}(#{signature}) - #{body} - end - CODE + def self.#{name}(#{signature}) + #{body} + end + CODE end private diff --git a/activerecord/lib/active_record/migration/command_recorder.rb b/activerecord/lib/active_record/migration/command_recorder.rb index 7e60aabc2d..44ea756028 100644 --- a/activerecord/lib/active_record/migration/command_recorder.rb +++ b/activerecord/lib/active_record/migration/command_recorder.rb @@ -125,10 +125,10 @@ module ActiveRecord }.each do |cmd, inv| [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse| class_eval <<-EOV, __FILE__, __LINE__ + 1 - def invert_#{method}(args, &block) # def invert_create_table(args, &block) - [:#{inverse}, args, block] # [:drop_table, args, block] - end # end - EOV + def invert_#{method}(args, &block) # def invert_create_table(args, &block) + [:#{inverse}, args, block] # [:drop_table, args, block] + end # end + EOV end end end diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index 86f8cb5d26..f0f88b120a 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -354,13 +354,13 @@ module ActiveRecord # associations are just regular associations. def generate_association_writer(association_name, type) generated_association_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1 - if method_defined?(:#{association_name}_attributes=) - remove_method(:#{association_name}_attributes=) - end - def #{association_name}_attributes=(attributes) - assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes) - end - eoruby + if method_defined?(:#{association_name}_attributes=) + remove_method(:#{association_name}_attributes=) + end + def #{association_name}_attributes=(attributes) + assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes) + end + eoruby end end @@ -519,14 +519,15 @@ module ActiveRecord # larger than the limit. def check_record_limit!(limit, attributes_collection) if limit - limit = case limit - when Symbol - send(limit) - when Proc - limit.call - else - limit - end + limit = \ + case limit + when Symbol + send(limit) + when Proc + limit.call + else + limit + end if limit && attributes_collection.size > limit raise TooManyRecords, "Maximum #{limit} records are allowed. Got #{attributes_collection.size} records instead." diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 376867675b..5e580ac865 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -466,9 +466,9 @@ module ActiveRecord if ActiveRecord::Base === id id = id.id ActiveSupport::Deprecation.warn(<<-MSG.squish) - You are passing an instance of ActiveRecord::Base to `find`. - Please pass the id of the object by calling `.id`. - MSG + You are passing an instance of ActiveRecord::Base to `find`. + Please pass the id of the object by calling `.id`. + MSG end relation = where(primary_key => id) diff --git a/activerecord/lib/active_record/relation/predicate_builder/class_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/class_handler.rb index 73ad864765..0a6574fcf1 100644 --- a/activerecord/lib/active_record/relation/predicate_builder/class_handler.rb +++ b/activerecord/lib/active_record/relation/predicate_builder/class_handler.rb @@ -18,9 +18,9 @@ module ActiveRecord def print_deprecation_warning ActiveSupport::Deprecation.warn(<<-MSG.squish) - Passing a class as a value in an Active Record query is deprecated and - will be removed. Pass a string instead. - MSG + Passing a class as a value in an Active Record query is deprecated and + will be removed. Pass a string instead. + MSG end end end diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 5a31f61d6d..78570140e5 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -59,11 +59,12 @@ module ActiveRecord FROZEN_EMPTY_HASH = {}.freeze Relation::VALUE_METHODS.each do |name| - method_name = case name - when *Relation::MULTI_VALUE_METHODS then "#{name}_values" - when *Relation::SINGLE_VALUE_METHODS then "#{name}_value" - when *Relation::CLAUSE_METHODS then "#{name}_clause" - end + method_name = \ + case name + when *Relation::MULTI_VALUE_METHODS then "#{name}_values" + when *Relation::SINGLE_VALUE_METHODS then "#{name}_value" + when *Relation::CLAUSE_METHODS then "#{name}_clause" + end class_eval <<-CODE, __FILE__, __LINE__ + 1 def #{method_name} # def includes_values get_value(#{name.inspect}) # get_value(:includes) @@ -470,7 +471,6 @@ module ActiveRecord self.left_outer_joins_values += args self end - alias :left_joins! :left_outer_joins! # Returns a new relation, which is the result of filtering the current relation # according to the conditions in the arguments. diff --git a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb index c8b89f1fdf..3a5e0b8dfe 100644 --- a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb @@ -105,7 +105,7 @@ module ActiveRecord GRANT ALL PRIVILEGES ON #{configuration['database']}.* TO '#{configuration['username']}'@'localhost' IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION; - SQL + SQL end def root_configuration_without_database diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb index 6eac9af236..a3a9430c03 100644 --- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb +++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb @@ -46,14 +46,15 @@ module ActiveRecord def structure_dump(filename) set_psql_env - search_path = case ActiveRecord::Base.dump_schemas - when :schema_search_path - configuration["schema_search_path"] - when :all - nil - when String - ActiveRecord::Base.dump_schemas - end + search_path = \ + case ActiveRecord::Base.dump_schemas + when :schema_search_path + configuration["schema_search_path"] + when :all + nil + when String + ActiveRecord::Base.dump_schemas + end args = ["-s", "-x", "-O", "-f", filename] unless search_path.blank? diff --git a/activerecord/test/cases/adapters/postgresql/rename_table_test.rb b/activerecord/test/cases/adapters/postgresql/rename_table_test.rb index 461353d239..e9e7f717ac 100644 --- a/activerecord/test/cases/adapters/postgresql/rename_table_test.rb +++ b/activerecord/test/cases/adapters/postgresql/rename_table_test.rb @@ -26,9 +26,9 @@ class PostgresqlRenameTableTest < ActiveRecord::PostgreSQLTestCase def num_indices_named(name) @connection.execute(<<-SQL).values.length - SELECT 1 FROM "pg_index" - JOIN "pg_class" ON "pg_index"."indexrelid" = "pg_class"."oid" - WHERE "pg_class"."relname" = '#{name}' - SQL + SELECT 1 FROM "pg_index" + JOIN "pg_class" ON "pg_index"."indexrelid" = "pg_class"."oid" + WHERE "pg_class"."relname" = '#{name}' + SQL end end diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb index d2f0710cb2..66f9349111 100644 --- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb @@ -431,9 +431,9 @@ module ActiveRecord def with_example_table(definition = nil, table_name = "ex", &block) definition ||= <<-SQL - id integer PRIMARY KEY AUTOINCREMENT, - number integer - SQL + id integer PRIMARY KEY AUTOINCREMENT, + number integer + SQL super(@conn, table_name, definition, &block) end end diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index 7a2041937d..993d9f8b94 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -1003,10 +1003,10 @@ class AttributeMethodsTest < ActiveRecord::TestCase def privatize(method_signature) @target.class_eval(<<-private_method, __FILE__, __LINE__ + 1) - private - def #{method_signature} - "I'm private" - end - private_method + private + def #{method_signature} + "I'm private" + end + private_method end end diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 7eae2363f8..08df945063 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -1,5 +1,6 @@ require "cases/helper" require "models/bird" +require "models/post" require "models/comment" require "models/company" require "models/customer" @@ -11,7 +12,6 @@ require "models/order" require "models/parrot" require "models/person" require "models/pirate" -require "models/post" require "models/reader" require "models/ship" require "models/ship_part" diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb index ce4e041793..925af49ffe 100644 --- a/activerecord/test/cases/relation/where_test.rb +++ b/activerecord/test/cases/relation/where_test.rb @@ -4,10 +4,10 @@ require "models/binary" require "models/cake_designer" require "models/car" require "models/chef" +require "models/post" require "models/comment" require "models/edge" require "models/essay" -require "models/post" require "models/price_estimate" require "models/topic" require "models/treasure" diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index 32b8781a6b..23d27ab90a 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -310,10 +310,10 @@ module ActiveRecord def skip_if_sqlite3_version_includes_quoting_bug if sqlite3_version_includes_quoting_bug? skip <<-ERROR.squish - You are using an outdated version of SQLite3 which has a bug in - quoted column names. Please update SQLite3 and rebuild the sqlite3 - ruby gem - ERROR + You are using an outdated version of SQLite3 which has a bug in + quoted column names. Please update SQLite3 and rebuild the sqlite3 + ruby gem + ERROR end end diff --git a/activerecord/test/cases/view_test.rb b/activerecord/test/cases/view_test.rb index aa3ff6160c..3cbfbc22c6 100644 --- a/activerecord/test/cases/view_test.rb +++ b/activerecord/test/cases/view_test.rb @@ -100,9 +100,9 @@ if ActiveRecord::Base.connection.supports_views? setup do @connection = ActiveRecord::Base.connection @connection.execute <<-SQL - CREATE VIEW paperbacks - AS SELECT name, status FROM books WHERE format = 'paperback' - SQL + CREATE VIEW paperbacks + AS SELECT name, status FROM books WHERE format = 'paperback' + SQL end teardown do @@ -162,9 +162,9 @@ if ActiveRecord::Base.connection.supports_views? setup do @connection = ActiveRecord::Base.connection @connection.execute <<-SQL - CREATE VIEW printed_books - AS SELECT id, name, status, format FROM books WHERE format = 'paperback' - SQL + CREATE VIEW printed_books + AS SELECT id, name, status, format FROM books WHERE format = 'paperback' + SQL end teardown do diff --git a/activesupport/lib/active_support/backtrace_cleaner.rb b/activesupport/lib/active_support/backtrace_cleaner.rb index e161ec4cca..169a58ecd1 100644 --- a/activesupport/lib/active_support/backtrace_cleaner.rb +++ b/activesupport/lib/active_support/backtrace_cleaner.rb @@ -14,7 +14,7 @@ module ActiveSupport # # bc = BacktraceCleaner.new # bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix - # bc.add_silencer { |line| line =~ /mongrel|rubygems/ } # skip any lines from mongrel or rubygems + # bc.add_silencer { |line| line =~ /puma|rubygems/ } # skip any lines from puma or rubygems # bc.clean(exception.backtrace) # perform the cleanup # # To reconfigure an existing BacktraceCleaner (like the default one in Rails) @@ -59,8 +59,8 @@ module ActiveSupport # Adds a silencer from the block provided. If the silencer returns +true+ # for a given line, it will be excluded from the clean backtrace. # - # # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb" - # backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ } + # # Will reject all lines that include the word "puma", like "/gems/puma/server.rb" or "/app/my_puma_server/rb" + # backtrace_cleaner.add_silencer { |line| line =~ /puma/ } def add_silencer(&block) @silencers << block end diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb index dbe55d7ce1..1a8477f9fe 100644 --- a/activesupport/lib/active_support/cache/memory_store.rb +++ b/activesupport/lib/active_support/cache/memory_store.rb @@ -4,7 +4,7 @@ module ActiveSupport module Cache # A cache store implementation which stores everything into memory in the # same process. If you're running multiple Ruby on Rails server processes - # (which is the case if you're using mongrel_cluster or Phusion Passenger), + # (which is the case if you're using Phusion Passenger or puma clustered mode), # then this means that Rails server process instances won't be able # to share cache data with each other and this may not be the most # appropriate cache in that scenario. diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index a33cab0504..ecf0c0eec7 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -297,9 +297,9 @@ module ActiveSupport def self.build(chain, filter, kind, options) if filter.is_a?(String) ActiveSupport::Deprecation.warn(<<-MSG.squish) - Passing string to define callback is deprecated and will be removed - in Rails 5.1 without replacement. - MSG + Passing string to define callback is deprecated and will be removed + in Rails 5.1 without replacement. + MSG end new chain.name, filter, kind, options, chain.config @@ -751,10 +751,10 @@ module ActiveSupport set_callbacks name, CallbackChain.new(name, options) module_eval <<-RUBY, __FILE__, __LINE__ + 1 - def _run_#{name}_callbacks(&block) - __run_callbacks__(_#{name}_callbacks, &block) - end - RUBY + def _run_#{name}_callbacks(&block) + __run_callbacks__(_#{name}_callbacks, &block) + end + RUBY end end @@ -787,9 +787,9 @@ module ActiveSupport def display_deprecation_warning_for_false_terminator ActiveSupport::Deprecation.warn(<<-MSG.squish) - Returning `false` in Active Record and Active Model callbacks will not implicitly halt a callback chain in Rails 5.1. - To explicitly halt the callback chain, please use `throw :abort` instead. - MSG + Returning `false` in Active Record and Active Model callbacks will not implicitly halt a callback chain in Rails 5.1. + To explicitly halt the callback chain, please use `throw :abort` instead. + MSG end end end diff --git a/activesupport/lib/active_support/core_ext/class/subclasses.rb b/activesupport/lib/active_support/core_ext/class/subclasses.rb index 8a21c71a42..10a7c787f6 100644 --- a/activesupport/lib/active_support/core_ext/class/subclasses.rb +++ b/activesupport/lib/active_support/core_ext/class/subclasses.rb @@ -6,7 +6,20 @@ class Class # Test if this Ruby supports each_object against singleton_class ObjectSpace.each_object(Numeric.singleton_class) {} - def descendants # :nodoc: + # Returns an array with all classes that are < than its receiver. + # + # class C; end + # C.descendants # => [] + # + # class B < C; end + # C.descendants # => [B] + # + # class A < B; end + # C.descendants # => [B, A] + # + # class D < C; end + # C.descendants # => [B, A, D] + def descendants descendants = [] ObjectSpace.each_object(singleton_class) do |k| descendants.unshift k unless k == self @@ -14,7 +27,7 @@ class Class descendants end rescue StandardError # JRuby 9.0.4.0 and earlier - def descendants # :nodoc: + def descendants descendants = [] ObjectSpace.each_object(Class) do |k| descendants.unshift k if k < self diff --git a/activesupport/lib/active_support/i18n_railtie.rb b/activesupport/lib/active_support/i18n_railtie.rb index 4749147ef4..08c9ef8f02 100644 --- a/activesupport/lib/active_support/i18n_railtie.rb +++ b/activesupport/lib/active_support/i18n_railtie.rb @@ -83,14 +83,15 @@ module I18n def self.init_fallbacks(fallbacks) include_fallbacks_module - args = case fallbacks - when ActiveSupport::OrderedOptions - [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact - when Hash, Array - Array.wrap(fallbacks) - else # TrueClass - [] - end + args = \ + case fallbacks + when ActiveSupport::OrderedOptions + [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact + when Hash, Array + Array.wrap(fallbacks) + else # TrueClass + [] + end I18n.fallbacks = I18n::Locale::Fallbacks.new(*args) end diff --git a/activesupport/test/xml_mini/jdom_engine_test.rb b/activesupport/test/xml_mini/jdom_engine_test.rb index a776ad25c4..816d57972c 100644 --- a/activesupport/test/xml_mini/jdom_engine_test.rb +++ b/activesupport/test/xml_mini/jdom_engine_test.rb @@ -180,7 +180,4 @@ if RUBY_PLATFORM.include?("java") assert_equal(hash, parsed_xml) end end - -else - # don't run these test because we aren't running in JRuby end diff --git a/guides/assets/stylesheets/main.css b/guides/assets/stylesheets/main.css index ed558e4793..b56699a0d0 100644 --- a/guides/assets/stylesheets/main.css +++ b/guides/assets/stylesheets/main.css @@ -16,7 +16,6 @@ .large {font-size: larger;} .hide {display: none;} -li ul, li ol { margin:0 1.5em; } ul, ol { margin: 0 1.5em 1.5em 1.5em; } ul { list-style-type: disc; } @@ -602,6 +601,8 @@ h6 { font-weight: normal; } +#subCol li ul, li ol { margin:0 1.5em; } + div.code_container { background: #EEE url(../images/tab_grey.gif) no-repeat left top; padding: 0.25em 1em 0.5em 48px; diff --git a/guides/bug_report_templates/active_job_gem.rb b/guides/bug_report_templates/active_job_gem.rb new file mode 100644 index 0000000000..debc46ad54 --- /dev/null +++ b/guides/bug_report_templates/active_job_gem.rb @@ -0,0 +1,32 @@ +begin + require "bundler/inline" +rescue LoadError => e + $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler" + raise e +end + +gemfile(true) do + source "https://rubygems.org" + # Activate the gem you are reporting the issue against. + gem "activejob", "5.0.0" +end + +require "minitest/autorun" +require "active_job" + +# Ensure backward compatibility with Minitest 4 +Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test) + +class BuggyJob < ActiveJob::Base + def perform + puts "performed" + end +end + +class BuggyJobTest < ActiveJob::TestCase + def test_stuff + assert_enqueued_with(job: BuggyJob) do + BuggyJob.perform_later + end + end +end diff --git a/guides/bug_report_templates/active_job_master.rb b/guides/bug_report_templates/active_job_master.rb new file mode 100644 index 0000000000..f61518713f --- /dev/null +++ b/guides/bug_report_templates/active_job_master.rb @@ -0,0 +1,31 @@ +begin + require "bundler/inline" +rescue LoadError => e + $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler" + raise e +end + +gemfile(true) do + source "https://rubygems.org" + gem "rails", github: "rails/rails" +end + +require "active_job" +require "minitest/autorun" + +# Ensure backward compatibility with Minitest 4 +Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test) + +class BuggyJob < ActiveJob::Base + def perform + puts "performed" + end +end + +class BuggyJobTest < ActiveJob::TestCase + def test_stuff + assert_enqueued_with(job: BuggyJob) do + BuggyJob.perform_later + end + end +end diff --git a/guides/source/5_0_release_notes.md b/guides/source/5_0_release_notes.md index 9c5ffb1d94..6538629972 100644 --- a/guides/source/5_0_release_notes.md +++ b/guides/source/5_0_release_notes.md @@ -797,6 +797,14 @@ Please refer to the [Changelog][active-record] for detailed changes. than the current time. ([Pull Request](https://github.com/rails/rails/pull/18956)) +* Change transaction callbacks to not swallow errors. + Before this change any errors raised inside a transaction callback + were getting rescued and printed in the logs, unless you used + the (newly deprecated) `raise_in_transactional_callbacks = true` option. + + Now these errors are not rescued anymore and just bubble up, as the other callbacks. + ([commit](https://github.com/rails/rails/commit/07d3d402341e81ada0214f2cb2be1da69eadfe72)) + Active Model ------------ diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md index a7975c7772..2a1c960887 100644 --- a/guides/source/active_record_callbacks.md +++ b/guides/source/active_record_callbacks.md @@ -431,4 +431,4 @@ class PictureFile < ApplicationRecord end ``` -WARNING. The `after_commit` and `after_rollback` callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block. If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback. +WARNING. The `after_commit` and `after_rollback` callbacks are called for all models created, updated, or destroyed within a transaction block. However, if an exception is raised within one of these callbacks, the exception will bubble up and any remaining `after_commit` or `after_rollback` methods will _not_ be executed. As such, if your callback code could raise an exception, you'll need to rescue it and handle it within the callback in order to allow other callbacks to run. diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md index aba4c6a97b..60a6c37f82 100644 --- a/guides/source/active_support_core_extensions.md +++ b/guides/source/active_support_core_extensions.md @@ -2036,7 +2036,7 @@ Addition only assumes the elements respond to `+`: ```ruby [[1, 2], [2, 3], [3, 4]].sum # => [1, 2, 2, 3, 3, 4] %w(foo bar baz).sum # => "foobarbaz" -{a: 1, b: 2, c: 3}.sum # => [:b, 2, :c, 3, :a, 1] +{a: 1, b: 2, c: 3}.sum # => [:b, 2, :c, 3, :a, 1] ``` The sum of an empty collection is zero by default, but this is customizable: diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md index 2e682b6951..3837cda553 100644 --- a/guides/source/association_basics.md +++ b/guides/source/association_basics.md @@ -387,7 +387,7 @@ The corresponding migration might look like this: class CreateSuppliers < ActiveRecord::Migration[5.0] def change create_table :suppliers do |t| - t.string :name + t.string :name t.timestamps end @@ -550,8 +550,8 @@ But what if you want to reload the cache, because data might have been changed b ```ruby author.books # retrieves books from the database author.books.size # uses the cached copy of books -author.books.reload.empty? # discards the cached copy of books - # and goes back to the database +author.books.reload.empty? # discards the cached copy of books + # and goes back to the database ``` ### Avoiding Name Collisions @@ -1841,7 +1841,7 @@ article = Article.create(name: 'a1') person.articles << article person.articles << article person.articles.inspect # => [#<Article id: 5, name: "a1">, #<Article id: 5, name: "a1">] -Reading.all.inspect # => [#<Reading id: 12, person_id: 5, article_id: 5>, #<Reading id: 13, person_id: 5, article_id: 5>] +Reading.all.inspect # => [#<Reading id: 12, person_id: 5, article_id: 5>, #<Reading id: 13, person_id: 5, article_id: 5>] ``` In the above case there are two readings and `person.articles` brings out both of @@ -1860,7 +1860,7 @@ article = Article.create(name: 'a1') person.articles << article person.articles << article person.articles.inspect # => [#<Article id: 7, name: "a1">] -Reading.all.inspect # => [#<Reading id: 16, person_id: 7, article_id: 7>, #<Reading id: 17, person_id: 7, article_id: 7>] +Reading.all.inspect # => [#<Reading id: 16, person_id: 7, article_id: 7>, #<Reading id: 17, person_id: 7, article_id: 7>] ``` In the above case there are still two readings. However `person.articles` shows diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md index a1b0029c47..fd7626250c 100644 --- a/guides/source/caching_with_rails.md +++ b/guides/source/caching_with_rails.md @@ -381,7 +381,7 @@ config.cache_store = :memory_store, { size: 64.megabytes } ``` If you're running multiple Ruby on Rails server processes (which is the case -if you're using mongrel_cluster or Phusion Passenger), then your Rails server +if you're using Phusion Passenger or puma clustered mode), then your Rails server process instances won't be able to share cache data with each other. This cache store is not appropriate for large application deployments. However, it can work well for small, low traffic sites with only a couple of server processes, diff --git a/guides/source/configuring.md b/guides/source/configuring.md index a115683134..fbf3c27957 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -71,7 +71,7 @@ These configuration methods are to be called on a `Rails::Railtie` object, such * `config.beginning_of_week` sets the default beginning of week for the application. Accepts a valid week day symbol (e.g. `:monday`). -* `config.cache_store` configures which cache store to use for Rails caching. Options include one of the symbols `:memory_store`, `:file_store`, `:mem_cache_store`, `:null_store`, or an object that implements the cache API. Defaults to `:file_store` if the directory `tmp/cache` exists, and to `:memory_store` otherwise. +* `config.cache_store` configures which cache store to use for Rails caching. Options include one of the symbols `:memory_store`, `:file_store`, `:mem_cache_store`, `:null_store`, or an object that implements the cache API. Defaults to `:file_store`. * `config.colorize_logging` specifies whether or not to use ANSI color codes when logging information. Defaults to `true`. @@ -131,7 +131,7 @@ defaults to `:debug` for all environments. The available log levels are: `:debug mylogger = MyLogger.new(STDOUT) mylogger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(mylogger) + config.logger = ActiveSupport::TaggedLogging.new(mylogger) ``` * `config.middleware` allows you to configure the application's middleware. This is covered in depth in the [Configuring Middleware](#configuring-middleware) section below. @@ -1198,7 +1198,7 @@ development: timeout: 5000 ``` -Since the connection pooling is handled inside of Active Record by default, all application servers (Thin, mongrel, Unicorn etc.) should behave the same. The database connection pool is initially empty. As demand for connections increases it will create them until it reaches the connection pool limit. +Since the connection pooling is handled inside of Active Record by default, all application servers (Thin, Puma, Unicorn etc.) should behave the same. The database connection pool is initially empty. As demand for connections increases it will create them until it reaches the connection pool limit. Any one request will check out a connection the first time it requires access to the database. At the end of the request it will check the connection back in. This means that the additional connection slot will be available again for the next request in the queue. diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md index 332d8fc852..5df16e68c9 100644 --- a/guides/source/contributing_to_ruby_on_rails.md +++ b/guides/source/contributing_to_ruby_on_rails.md @@ -41,6 +41,7 @@ Having a way to reproduce your issue will be very helpful for others to help con * Template for Active Record (models, database) issues: [gem](https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_record_gem.rb) / [master](https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_record_master.rb) * Template for Action Pack (controllers, routing) issues: [gem](https://github.com/rails/rails/blob/master/guides/bug_report_templates/action_controller_gem.rb) / [master](https://github.com/rails/rails/blob/master/guides/bug_report_templates/action_controller_master.rb) +* Template for Active Job issues: [gem](https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_job_gem.rb) / [master](https://github.com/rails/rails/blob/master/guides/bug_report_templates/active_job_master.rb) * Generic template for other issues: [gem](https://github.com/rails/rails/blob/master/guides/bug_report_templates/generic_gem.rb) / [master](https://github.com/rails/rails/blob/master/guides/bug_report_templates/generic_master.rb) These templates include the boilerplate code to set up a test case against either a released version of Rails (`*_gem.rb`) or edge Rails (`*_master.rb`). diff --git a/guides/source/engines.md b/guides/source/engines.md index d6118c014f..83c0a7f337 100644 --- a/guides/source/engines.md +++ b/guides/source/engines.md @@ -46,7 +46,7 @@ see how to hook it into an application. Engines can also be isolated from their host applications. This means that an application is able to have a path provided by a routing helper such as -`articles_path` and use an engine also that provides a path also called +`articles_path` and use an engine that also provides a path also called `articles_path`, and the two would not clash. Along with this, controllers, models and table names are also namespaced. You'll see how to do this later in this guide. diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index c4a8eacc57..31d5c4f71d 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -633,8 +633,7 @@ this situation, the only parameters that matter are the ones from the form. TIP: Ensure you have a firm grasp of the `params` method, as you'll use it fairly regularly. Let's consider an example URL: **http://www.example.com/?username=dhh&email=dhh@email.com**. In this URL, `params[:username]` would equal "dhh" and `params[:email]` would equal "dhh@email.com". -If you re-submit the form one more time you'll now no longer get the missing -template error. Instead, you'll see something that looks like the following: +If you re-submit the form one more time, you'll see something that looks like the following: ```ruby <ActionController::Parameters {"title"=>"First Article!", "text"=>"This is my first article."} permitted: false> diff --git a/guides/source/initialization.md b/guides/source/initialization.md index a2eec03eba..57ed35d0d8 100644 --- a/guides/source/initialization.md +++ b/guides/source/initialization.md @@ -318,7 +318,7 @@ def parse!(args) args, options = args.dup, {} opt_parser = OptionParser.new do |opts| - opts.banner = "Usage: rails server [mongrel, thin, etc] [options]" + opts.banner = "Usage: rails server [puma, thin, etc] [options]" opts.on("-p", "--port=port", Integer, "Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v } ... @@ -663,7 +663,7 @@ DEFAULT_OPTIONS = { } def self.run(app, options = {}) - options = DEFAULT_OPTIONS.merge(options) + options = DEFAULT_OPTIONS.merge(options) if options[:Verbose] app = Rack::CommonLogger.new(app, STDOUT) diff --git a/guides/source/security.md b/guides/source/security.md index 5c3d465220..aea9728c10 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -131,7 +131,7 @@ It works like this: * The user takes the cookie from the first step (which they previously copied) and replaces the current cookie in the browser. * The user has their original credit back. -Including a nonce (a random value) in the session solves replay attacks. A nonce is valid only once, and the server has to keep track of all the valid nonces. It gets even more complicated if you have several application servers (mongrels). Storing nonces in a database table would defeat the entire purpose of CookieStore (avoiding accessing the database). +Including a nonce (a random value) in the session solves replay attacks. A nonce is valid only once, and the server has to keep track of all the valid nonces. It gets even more complicated if you have several application servers. Storing nonces in a database table would defeat the entire purpose of CookieStore (avoiding accessing the database). The best _solution against it is not to store this kind of data in a session, but in the database_. In this case store the credit in the database and the logged_in_user_id in the session. diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index 0339849bfe..1eabf3fef3 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -23,7 +23,7 @@ module Rails def option_parser(options) OptionParser.new do |opts| - opts.banner = "Usage: rails server [mongrel, thin etc] [options]" + opts.banner = "Usage: rails server [puma, thin etc] [options]" opts.on("-p", "--port=port", Integer, "Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v } opts.on("-b", "--binding=IP", String, diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 7d061ed27c..d76acbdafc 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -162,14 +162,15 @@ module Rails def set_default_accessors! self.destination_root = File.expand_path(app_path, destination_root) - self.rails_template = case options[:template] - when /^https?:\/\// - options[:template] - when String - File.expand_path(options[:template], Dir.pwd) + self.rails_template = \ + case options[:template] + when /^https?:\/\// + options[:template] + when String + File.expand_path(options[:template], Dir.pwd) else - options[:template] - end + options[:template] + end end def database_gemfile_entry diff --git a/railties/lib/rails/templates/rails/mailers/email.html.erb b/railties/lib/rails/templates/rails/mailers/email.html.erb index fed96fbc85..c63781ed0c 100644 --- a/railties/lib/rails/templates/rails/mailers/email.html.erb +++ b/railties/lib/rails/templates/rails/mailers/email.html.erb @@ -88,7 +88,10 @@ <% unless @email.attachments.nil? || @email.attachments.empty? %> <dt>Attachments:</dt> <dd> - <%= @email.attachments.map { |a| a.respond_to?(:original_filename) ? a.original_filename : a.filename }.join(', ') %> + <% @email.attachments.each do |a| %> + <% filename = a.respond_to?(:original_filename) ? a.original_filename : a.filename %> + <%= link_to filename, "data:application/octet-stream;charset=utf-8;base64,#{Base64.encode64(a.body.to_s)}", download: filename %> + <% end %> </dd> <% end %> |