aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb20
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb3
-rw-r--r--activerecord/lib/active_record/attribute_set/builder.rb21
-rw-r--r--activerecord/lib/active_record/inheritance.rb12
-rw-r--r--activerecord/lib/active_record/persistence.rb28
-rw-r--r--activerecord/lib/active_record/querying.rb2
-rw-r--r--activerecord/lib/active_record/result.rb9
-rw-r--r--activesupport/CHANGELOG.md6
-rw-r--r--activesupport/lib/active_support/core_ext/string/filters.rb9
-rw-r--r--activesupport/test/core_ext/range_ext_test.rb4
-rw-r--r--activesupport/test/core_ext/string_ext_test.rb6
-rw-r--r--guides/source/4_1_release_notes.md2
-rw-r--r--guides/source/4_2_release_notes.md15
-rw-r--r--guides/source/upgrading_ruby_on_rails.md4
14 files changed, 100 insertions, 41 deletions
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index 591f881a53..ac1f209232 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -135,18 +135,6 @@ module ActionController #:nodoc:
#
# render json: @people
#
- # Since this is a common pattern, you can use the class method respond_to
- # with the respond_with method to have the same results:
- #
- # class PeopleController < ApplicationController
- # respond_to :html, :xml, :json
- #
- # def index
- # @people = Person.all
- # respond_with(@people)
- # end
- # end
- #
# Formats can have different variants.
#
# The request variant is a specialization of the request format, like <tt>:tablet</tt>,
@@ -214,8 +202,8 @@ module ActionController #:nodoc:
# format.html.phone # this gets rendered
# end
#
- # Be sure to check the documentation of +respond_with+ and
- # <tt>ActionController::MimeResponds.respond_to</tt> for more examples.
+ # Be sure to check the documentation of <tt>ActionController::MimeResponds.respond_to</tt>
+ # for more examples.
def respond_to(*mimes)
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
@@ -234,8 +222,8 @@ module ActionController #:nodoc:
# A container for responses available from the current controller for
# requests for different mime-types sent to a particular action.
#
- # The public controller methods +respond_with+ and +respond_to+ may be called
- # with a block that is used to define responses to different mime-types, e.g.
+ # The public controller methods +respond_to+ may be called with a block
+ # that is used to define responses to different mime-types, e.g.
# for +respond_to+ :
#
# respond_to do |format|
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index bc94536c8c..45d3962494 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -86,8 +86,7 @@ module ActionController
# end
# end
# To use renderers and their mime types in more concise ways, see
- # <tt>ActionController::MimeResponds::ClassMethods.respond_to</tt> and
- # <tt>ActionController::MimeResponds#respond_with</tt>
+ # <tt>ActionController::MimeResponds::ClassMethods.respond_to</tt>
def self.add(key, &block)
define_method(_render_with_renderer_method_name(key), &block)
RENDERERS << key.to_sym
diff --git a/activerecord/lib/active_record/attribute_set/builder.rb b/activerecord/lib/active_record/attribute_set/builder.rb
index d4a787f2fe..0a62c68bfb 100644
--- a/activerecord/lib/active_record/attribute_set/builder.rb
+++ b/activerecord/lib/active_record/attribute_set/builder.rb
@@ -8,18 +8,33 @@ module ActiveRecord
end
def build_from_database(values = {}, additional_types = {})
- attributes = build_attributes_from_values(values, additional_types)
+ build_from_database_pairs(values.keys, values.values, additional_types)
+ end
+
+ def build_from_database_pairs(columns, values, additional_types)
+ attributes = build_attributes_from_values(columns, values, additional_types)
add_uninitialized_attributes(attributes)
AttributeSet.new(attributes)
end
private
- def build_attributes_from_values(values, additional_types)
- values.each_with_object({}) do |(name, value), hash|
+ def build_attributes_from_values(columns, values, additional_types)
+ # We are performing manual iteration here as this method is a performance
+ # hotspot
+ hash = {}
+ index = 0
+ length = columns.length
+
+ while index < length
+ name = columns[index]
+ value = values[index]
type = additional_types.fetch(name, types[name])
hash[name] = Attribute.from_database(name, value, type)
+ index += 1
end
+
+ hash
end
def add_uninitialized_attributes(attributes)
diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb
index f58145ab05..4aad3217cb 100644
--- a/activerecord/lib/active_record/inheritance.rb
+++ b/activerecord/lib/active_record/inheritance.rb
@@ -165,15 +165,19 @@ module ActiveRecord
# record instance. For single-table inheritance, we check the record
# for a +type+ column and return the corresponding class.
def discriminate_class_for_record(record)
- if using_single_table_inheritance?(record)
- find_sti_class(record[inheritance_column])
+ discriminate_class_for_value(record[inheritance_column])
+ end
+
+ def discriminate_class_for_value(value)
+ if using_single_table_inheritance?(value)
+ find_sti_class(value)
else
super
end
end
- def using_single_table_inheritance?(record)
- record[inheritance_column].present? && columns_hash.include?(inheritance_column)
+ def using_single_table_inheritance?(value)
+ value.present? && columns_hash.include?(inheritance_column)
end
def find_sti_class(type_name)
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 755ff2b2f1..9d2c9d3b9c 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -65,19 +65,41 @@ module ActiveRecord
# how this "single-table" inheritance mapping is implemented.
def instantiate(attributes, column_types = {})
klass = discriminate_class_for_record(attributes)
- attributes = klass.attributes_builder.build_from_database(attributes, column_types)
- klass.allocate.init_with('attributes' => attributes, 'new_record' => false)
+ klass.instantiate_pairs(attributes.keys, attributes.values, column_types)
+ end
+
+ def instantiate_pairs(columns, values, column_types = {}) # :nodoc:
+ attributes = attributes_builder.build_from_database_pairs(columns, values, column_types)
+ allocate.init_with('attributes' => attributes, 'new_record' => false)
+ end
+
+ def instantiate_result_set(result_set, column_types = {}) # :nodoc:
+ inheritance_column_index = inheritance_column && result_set.columns.find_index(inheritance_column)
+
+ result_set.each_pair.map do |columns, values|
+ inheritance_value = inheritance_column_index && values[inheritance_column_index]
+ klass = discriminate_class_for_value(inheritance_value)
+ klass.instantiate_pairs(columns, values, column_types)
+ end
end
private
# Called by +instantiate+ to decide which class to use for a new
# record instance.
#
- # See +ActiveRecord::Inheritance#discriminate_class_for_record+ for
+ # See +ActiveRecord::Inheritance#discriminate_class_for_value+ for
# the single-table inheritance discriminator.
+ def discriminate_class_for_value(*)
+ self
+ end
+
def discriminate_class_for_record(record)
self
end
+
+ def inheritance_column
+ nil
+ end
end
# Returns true if this object hasn't been saved yet -- that is, a record
diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb
index e8de4db3a7..9d4df81b07 100644
--- a/activerecord/lib/active_record/querying.rb
+++ b/activerecord/lib/active_record/querying.rb
@@ -47,7 +47,7 @@ module ActiveRecord
}
message_bus.instrument('instantiation.active_record', payload) do
- result_set.map { |record| instantiate(record, column_types) }
+ instantiate_result_set(result_set, column_types)
end
end
diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb
index 3a3e65ef32..c84ad586e2 100644
--- a/activerecord/lib/active_record/result.rb
+++ b/activerecord/lib/active_record/result.rb
@@ -54,6 +54,15 @@ module ActiveRecord
end
end
+ def each_pair
+ return to_enum(__method__) unless block_given?
+
+ columns = @columns.map { |c| c.dup.freeze }
+ @rows.each do |row|
+ yield columns, row
+ end
+ end
+
def to_hash
hash_rows
end
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index b2b3cf4bd4..468b990f39 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -2,12 +2,12 @@
*Pavel Pravosud*
-* TimeWithZone#strftime now delegates every directive to Time#strftime except for '%Z',
+* `TimeWithZone#strftime` now delegates every directive to `Time#strftime` except for '%Z',
it also now correctly handles escaped '%' characters placed just before time zone related directives.
*Pablo Herrero*
-* Corrected Inflector#underscore handling of multiple successive acroynms.
+* Corrected `Inflector#underscore` handling of multiple successive acroynms.
*James Le Cuirot*
@@ -160,7 +160,7 @@
* Fixed `ActiveSupport::Cache::FileStore` exploding with long paths.
- *Adam Panzer / Michael Grosser*
+ *Adam Panzer*, *Michael Grosser*
* Fixed `ActiveSupport::TimeWithZone#-` so precision is not unnecessarily lost
when working with objects with a nanosecond component.
diff --git a/activesupport/lib/active_support/core_ext/string/filters.rb b/activesupport/lib/active_support/core_ext/string/filters.rb
index 499b9b26bc..096292dc58 100644
--- a/activesupport/lib/active_support/core_ext/string/filters.rb
+++ b/activesupport/lib/active_support/core_ext/string/filters.rb
@@ -13,6 +13,9 @@ class String
end
# Performs a destructive squish. See String#squish.
+ # str = " foo bar \n \t boo"
+ # str.squish! # => "foo bar boo"
+ # str # => "foo bar boo"
def squish!
gsub!(/\A[[:space:]]+/, '')
gsub!(/[[:space:]]+\z/, '')
@@ -21,11 +24,17 @@ class String
end
# Returns a new string with all occurrences of the patterns removed.
+ # str = "foo bar test"
+ # str.remove(" test") # => "foo bar"
+ # str # => "foo bar test"
def remove(*patterns)
dup.remove!(*patterns)
end
# Alters the string by removing all occurrences of the patterns.
+ # str = "foo bar test"
+ # str.remove!(" test") # => "foo bar"
+ # str # => "foo bar"
def remove!(*patterns)
patterns.each do |pattern|
gsub! pattern, ""
diff --git a/activesupport/test/core_ext/range_ext_test.rb b/activesupport/test/core_ext/range_ext_test.rb
index 98c4ec6b5e..f096328cee 100644
--- a/activesupport/test/core_ext/range_ext_test.rb
+++ b/activesupport/test/core_ext/range_ext_test.rb
@@ -115,11 +115,11 @@ class RangeTest < ActiveSupport::TestCase
def test_date_time_with_each
datetime = DateTime.now
- assert ((datetime - 1.hour)..datetime).each {}
+ assert(((datetime - 1.hour)..datetime).each {})
end
def test_date_time_with_step
datetime = DateTime.now
- assert ((datetime - 1.hour)..datetime).step(1) {}
+ assert(((datetime - 1.hour)..datetime).step(1) {})
end
end
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index 119e62369d..e32c178951 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -266,6 +266,12 @@ class StringInflectionsTest < ActiveSupport::TestCase
assert_equal "This is a good day to die", original
end
+ def test_remove_for_multiple_occurrences
+ original = "This is a good day to die to die"
+ assert_equal "This is a good day", original.remove(" to die")
+ assert_equal "This is a good day to die to die", original
+ end
+
def test_remove!
original = "This is a very good day to die"
assert_equal "This is a good day to die", original.remove!(" very")
diff --git a/guides/source/4_1_release_notes.md b/guides/source/4_1_release_notes.md
index 52a5acb75e..c7877a9cb5 100644
--- a/guides/source/4_1_release_notes.md
+++ b/guides/source/4_1_release_notes.md
@@ -136,7 +136,7 @@ end
### Action Mailer Previews
-Action Mailer previews provide a way to visually see how emails look by visiting
+Action Mailer previews provide a way to see how emails look by visiting
a special URL that renders them.
You implement a preview class whose methods return the mail object you'd like
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md
index 3a9be62865..8553cffa9d 100644
--- a/guides/source/4_2_release_notes.md
+++ b/guides/source/4_2_release_notes.md
@@ -300,6 +300,9 @@ Please refer to the [Changelog][railties] for detailed changes.
### Removals
+* The `--skip-action-view` option has been removed from the
+ app generator. ([Pull Request](https://github.com/rails/rails/pull/17042))
+
* The `rails application` command has been removed without replacement.
([Pull Request](https://github.com/rails/rails/pull/11616))
@@ -575,6 +578,10 @@ Please refer to the [Changelog][active-record] for detailed changes.
### Deprecations
+* Deprecated `sanitize_sql_hash_for_conditions` without replacement. Using a
+ `Relation` for performing queries and updates is the prefered API.
+ ([Commit](https://github.com/rails/rails/commit/d5902c9e))
+
* Deprecated swallowing of errors inside `after_commit` and `after_rollback`.
([Pull Request](https://github.com/rails/rails/pull/16537))
@@ -753,15 +760,15 @@ Please refer to the [Changelog][active-support] for detailed changes.
### Notable changes
-* `Object#try` and `Object#try!` can now be used without an explicit receiver.
- ([Commit](https://github.com/rails/rails/commit/5e51bdda59c9ba8e5faf86294e3e431bd45f1830),
- [Pull Request](https://github.com/rails/rails/pull/17361))
-
* Introduced new configuration option `active_support.test_order` for
specifying the order test cases are executed. This option currently defaults
to `:sorted` but will be changed to `:random` in Rails 5.0.
([Commit](https://github.com/rails/rails/commit/53e877f7d9291b2bf0b8c425f9e32ef35829f35b))
+* `Object#try` and `Object#try!` can now be used without an explicit receiver.
+ ([Commit](https://github.com/rails/rails/commit/5e51bdda59c9ba8e5faf86294e3e431bd45f1830),
+ [Pull Request](https://github.com/rails/rails/pull/17361))
+
* The `travel_to` test helper now truncates the `usec` component to 0.
([Commit](https://github.com/rails/rails/commit/9f6e82ee4783e491c20f5244a613fdeb4024beb5))
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index aac2aef615..25759a0c77 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -181,7 +181,7 @@ end
There's a new choice for sanitizing HTML fragments in your applications. The
venerable html-scanner approach is now officially being deprecated in favor of
-[`Rails Html Sanitizer`](https://github.com/rails/rails-html-sanitizer).
+[`Rails HTML Sanitizer`](https://github.com/rails/rails-html-sanitizer).
This means the methods `sanitize`, `sanitize_css`, `strip_tags` and
`strip_links` are backed by a new implementation.
@@ -207,7 +207,7 @@ gem 'rails-deprecated_sanitizer'
```
### Rails DOM Testing
-The [`TagAssertions` module](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/TagAssertions.html) (containing methods such as `assert_tag`), [has been deprecated](https://github.com/rails/rails/blob/6061472b8c310158a2a2e8e9a6b81a1aef6b60fe/actionpack/lib/action_dispatch/testing/assertions/dom.rb) in favor of the `assert_select` methods from the `SelectorAssertions` module, which has been extracted into the [rails-dom-testing gem](https://github.com/rails/rails-dom-testing).
+The [`TagAssertions` module](http://api.rubyonrails.org/classes/ActionDispatch/Assertions/TagAssertions.html) (containing methods such as `assert_tag`), [has been deprecated](https://github.com/rails/rails/blob/6061472b8c310158a2a2e8e9a6b81a1aef6b60fe/actionpack/lib/action_dispatch/testing/assertions/dom.rb) in favor of the `assert_select` methods from the `SelectorAssertions` module, which has been extracted into the [rails-dom-testing gem](https://github.com/rails/rails-dom-testing).
### Masked Authenticity Tokens