aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RELEASING_RAILS.rdoc4
-rw-r--r--actionpack/lib/action_controller/test_case.rb8
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb2
-rw-r--r--actionpack/test/controller/integration_test.rb6
-rw-r--r--actionpack/test/controller/test_case_test.rb21
-rw-r--r--actionview/lib/action_view/helpers/date_helper.rb2
-rw-r--r--actionview/lib/action_view/test_case.rb9
-rw-r--r--actionview/test/template/date_helper_test.rb2
-rw-r--r--activerecord/lib/active_record/aggregations.rb4
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb4
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/primary_key.rb2
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb18
-rw-r--r--activerecord/lib/active_record/attribute_set.rb4
-rw-r--r--activerecord/lib/active_record/attribute_set/builder.rb14
-rw-r--r--activerecord/lib/active_record/enum.rb2
-rw-r--r--activerecord/lib/active_record/reflection.rb2
-rw-r--r--activerecord/lib/active_record/relation.rb6
-rw-r--r--activerecord/lib/active_record/type/integer.rb5
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb2
-rw-r--r--activerecord/test/cases/inheritance_test.rb2
-rw-r--r--guides/source/3_0_release_notes.md2
25 files changed, 83 insertions, 46 deletions
diff --git a/RELEASING_RAILS.rdoc b/RELEASING_RAILS.rdoc
index f8c40f0b02..c80a5816a7 100644
--- a/RELEASING_RAILS.rdoc
+++ b/RELEASING_RAILS.rdoc
@@ -28,7 +28,7 @@ Do not release with Red AWDwR tests.
=== Are the supported plugins working? If not, make it work.
Some Rails plugins are important and need to be supported until Rails 5.
-As these plugins are outside the Rails repository it is easy to break then without knowing
+As these plugins are outside the Rails repository it is easy to break them without knowing
after some refactoring or bug fix, so it is important to check if the following plugins
are working with the versions that will be released:
@@ -54,7 +54,7 @@ addressed, and that can impact your release date.
Ruby implementors have high stakes in making sure Rails works. Be kind and
give them a heads up that Rails will be released soonish.
-This only needs done for major and minor releases, bugfix releases aren't a
+This only need to be done for major and minor releases, bugfix releases aren't a
big enough deal, and are supposed to be backwards compatible.
Send an email just giving a heads up about the upcoming release to these
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 097019144c..30eae41f60 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -679,10 +679,6 @@ module ActionController
klass.new
end
- def document_root_element
- html_document
- end
-
included do
include ActionController::TemplateAssertions
include ActionDispatch::Assertions
@@ -692,6 +688,10 @@ module ActionController
private
+ def document_root_element
+ html_document.root
+ end
+
def check_required_ivars
# Sanity check for required instance variables so we can give an
# understandable error message.
diff --git a/actionpack/lib/action_dispatch/testing/assertions.rb b/actionpack/lib/action_dispatch/testing/assertions.rb
index 41d00b5e2b..f325c35b57 100644
--- a/actionpack/lib/action_dispatch/testing/assertions.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions.rb
@@ -15,7 +15,7 @@ module ActionDispatch
@html_document ||= if @response.content_type =~ /xml$/
Nokogiri::XML::Document.parse(@response.body)
else
- Nokogiri::HTML::DocumentFragment.parse(@response.body)
+ Nokogiri::HTML::Document.parse(@response.body)
end
end
end
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 731305227d..a9a1576fed 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -505,7 +505,7 @@ module ActionDispatch
end
def document_root_element
- html_document
+ html_document.root
end
end
end
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index 27b30536b0..d6219b7626 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -292,7 +292,7 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
assert_equal({}, cookies.to_hash)
assert_equal "OK", body
assert_equal "OK", response.body
- assert_kind_of Nokogiri::HTML::DocumentFragment, html_document
+ assert_kind_of Nokogiri::HTML::Document, html_document
assert_equal 1, request_count
end
end
@@ -308,7 +308,7 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
assert_equal({}, cookies.to_hash)
assert_equal "Created", body
assert_equal "Created", response.body
- assert_kind_of Nokogiri::HTML::DocumentFragment, html_document
+ assert_kind_of Nokogiri::HTML::Document, html_document
assert_equal 1, request_count
end
end
@@ -368,7 +368,7 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
assert_response :redirect
assert_response :found
assert_equal "<html><body>You are being <a href=\"http://www.example.com/get\">redirected</a>.</body></html>", response.body
- assert_kind_of Nokogiri::HTML::DocumentFragment, html_document
+ assert_kind_of Nokogiri::HTML::Document, html_document
assert_equal 1, request_count
follow_redirect!
diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb
index 957c0a5288..475af90032 100644
--- a/actionpack/test/controller/test_case_test.rb
+++ b/actionpack/test/controller/test_case_test.rb
@@ -132,6 +132,14 @@ XML
render :nothing => true
end
+ def test_without_body
+ render html: '<div class="foo"></div>'.html_safe
+ end
+
+ def test_with_body
+ render html: '<body class="foo"></body>'.html_safe
+ end
+
private
def generate_url(opts)
@@ -179,6 +187,19 @@ XML
end
end
+ def test_assert_select_without_body
+ get :test_without_body
+
+ assert_select 'body', 0
+ assert_select 'div.foo'
+ end
+
+ def test_assert_select_with_body
+ get :test_with_body
+
+ assert_select 'body.foo'
+ end
+
def test_url_options_reset
@controller = DefaultUrlOptionsCachingController.new
get :test_url_options_reset
diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb
index 01a9747035..bd7b36c352 100644
--- a/actionview/lib/action_view/helpers/date_helper.rb
+++ b/actionview/lib/action_view/helpers/date_helper.rb
@@ -177,7 +177,7 @@ module ActionView
# and +:name+ (string). A format string would be something like "%{name} (%<number>02d)" for example.
# See <tt>Kernel.sprintf</tt> for documentation on format sequences.
# * <tt>:date_separator</tt> - Specifies a string to separate the date fields. Default is "" (i.e. nothing).
- # * <tt>:start_year</tt> - Set the start year for the year select. Default is <tt>Date.today.year - 5</tt>if
+ # * <tt>:start_year</tt> - Set the start year for the year select. Default is <tt>Date.today.year - 5</tt> if
# you are creating new record. While editing existing record, <tt>:start_year</tt> defaults to
# the current selected year minus 5.
# * <tt>:end_year</tt> - Set the end year for the year select. Default is <tt>Date.today.year + 5</tt> if
diff --git a/actionview/lib/action_view/test_case.rb b/actionview/lib/action_view/test_case.rb
index 5cffddcd4f..812b011bd7 100644
--- a/actionview/lib/action_view/test_case.rb
+++ b/actionview/lib/action_view/test_case.rb
@@ -126,10 +126,6 @@ module ActionView
end
# Need to experiment if this priority is the best one: rendered => output_buffer
- def document_root_element
- Nokogiri::HTML::DocumentFragment.parse(@rendered.blank? ? @output_buffer : @rendered)
- end
-
class RenderedViewsCollection
def initialize
@rendered_views ||= Hash.new { |hash, key| hash[key] = [] }
@@ -161,6 +157,11 @@ module ActionView
private
+ # Need to experiment if this priority is the best one: rendered => output_buffer
+ def document_root_element
+ Nokogiri::HTML::Document.parse(@rendered.blank? ? @output_buffer : @rendered).root
+ end
+
def say_no_to_protect_against_forgery!
_helpers.module_eval do
remove_possible_method :protect_against_forgery?
diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb
index 0cdb130710..a6962b5200 100644
--- a/actionview/test/template/date_helper_test.rb
+++ b/actionview/test/template/date_helper_test.rb
@@ -1504,7 +1504,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="">Choose seconds</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), :prompt => true, :include_seconds => true,
+ assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), :include_seconds => true,
:prompt => {:hour => 'Choose hour', :minute => 'Choose minute', :second => 'Choose seconds'})
end
diff --git a/activerecord/lib/active_record/aggregations.rb b/activerecord/lib/active_record/aggregations.rb
index e576ec4d40..1040e6e3bb 100644
--- a/activerecord/lib/active_record/aggregations.rb
+++ b/activerecord/lib/active_record/aggregations.rb
@@ -230,8 +230,8 @@ module ActiveRecord
private
def reader_method(name, class_name, mapping, allow_nil, constructor)
define_method(name) do
- if @aggregation_cache[name].nil? && (!allow_nil || mapping.any? {|key, _| !read_attribute(key).nil? })
- attrs = mapping.collect {|key, _| read_attribute(key)}
+ if @aggregation_cache[name].nil? && (!allow_nil || mapping.any? {|key, _| !_read_attribute(key).nil? })
+ attrs = mapping.collect {|key, _| _read_attribute(key)}
object = constructor.respond_to?(:call) ?
constructor.call(*attrs) :
class_name.constantize.send(constructor, *attrs)
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index 1413efaf7f..93084e0dcf 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -66,7 +66,7 @@ module ActiveRecord
# the loaded flag is set to true as well.
def count_records
count = if has_cached_counter?
- owner.read_attribute cached_counter_attribute_name
+ owner._read_attribute cached_counter_attribute_name
else
scope.count
end
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index bde23fc116..6329fdfe95 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -20,7 +20,7 @@ module ActiveRecord
# SELECT query will be generated by using #length instead.
def size
if has_cached_counter?
- owner.read_attribute cached_counter_attribute_name(reflection)
+ owner._read_attribute cached_counter_attribute_name(reflection)
elsif loaded?
target.size
else
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 34ec397aee..d766996d37 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -332,7 +332,7 @@ module ActiveRecord
# task.attribute_present?(:title) # => true
# task.attribute_present?(:is_done) # => true
def attribute_present?(attribute)
- value = read_attribute(attribute)
+ value = _read_attribute(attribute)
!value.nil? && !(value.respond_to?(:empty?) && value.empty?)
end
@@ -433,7 +433,7 @@ module ActiveRecord
end
def typecasted_attribute_value(name)
- read_attribute(name)
+ _read_attribute(name)
end
end
end
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 2f02738f6d..9ba46ec4c7 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -110,7 +110,7 @@ module ActiveRecord
if attribute_changed?(attr)
changed_attributes[attr]
else
- clone_attribute_value(:read_attribute, attr)
+ clone_attribute_value(:_read_attribute, attr)
end
end
diff --git a/activerecord/lib/active_record/attribute_methods/primary_key.rb b/activerecord/lib/active_record/attribute_methods/primary_key.rb
index 104d84a1f8..c28374e4ab 100644
--- a/activerecord/lib/active_record/attribute_methods/primary_key.rb
+++ b/activerecord/lib/active_record/attribute_methods/primary_key.rb
@@ -17,7 +17,7 @@ module ActiveRecord
def id
if pk = self.class.primary_key
sync_with_transaction_state
- read_attribute(pk)
+ _read_attribute(pk)
end
end
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index bf2a084a00..20f0936e52 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -27,7 +27,7 @@ module ActiveRecord
<<-EOMETHOD
def #{method_name}
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{const_name}
- read_attribute(name) { |n| missing_attribute(n, caller) }
+ _read_attribute(name) { |n| missing_attribute(n, caller) }
end
EOMETHOD
end
@@ -64,7 +64,7 @@ module ActiveRecord
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) }
+ _read_attribute(name) { |n| missing_attribute(n, caller) }
end
STR
@@ -76,19 +76,27 @@ module ActiveRecord
end
end
+ ID = 'id'.freeze
+
# Returns the value of the attribute identified by <tt>attr_name</tt> after
# it has been typecast (for example, "2004-12-12" in a date column is cast
# to a date object, like Date.new(2004, 12, 12)).
def read_attribute(attr_name, &block)
name = attr_name.to_s
- name = self.class.primary_key if name == 'id'
- @attributes.fetch_value(name, &block)
+ name = self.class.primary_key if name == ID
+ _read_attribute(name, &block)
+ end
+
+ # This method exists to avoid the expensive primary_key check internally, without
+ # breaking compatibility with the read_attribute API
+ def _read_attribute(attr_name) # :nodoc:
+ @attributes.fetch_value(attr_name.to_s) { |n| yield n if block_given? }
end
private
def attribute(attribute_name)
- read_attribute(attribute_name)
+ _read_attribute(attribute_name)
end
end
end
diff --git a/activerecord/lib/active_record/attribute_set.rb b/activerecord/lib/active_record/attribute_set.rb
index 21c58cbf1d..6b1d7ea79e 100644
--- a/activerecord/lib/active_record/attribute_set.rb
+++ b/activerecord/lib/active_record/attribute_set.rb
@@ -27,8 +27,8 @@ module ActiveRecord
attributes.initialized_keys
end
- def fetch_value(name, &block)
- self[name].value(&block)
+ def fetch_value(name)
+ self[name].value { |n| yield n if block_given? }
end
def write_from_database(name, value)
diff --git a/activerecord/lib/active_record/attribute_set/builder.rb b/activerecord/lib/active_record/attribute_set/builder.rb
index 60154a0647..05138ae36d 100644
--- a/activerecord/lib/active_record/attribute_set/builder.rb
+++ b/activerecord/lib/active_record/attribute_set/builder.rb
@@ -19,7 +19,7 @@ module ActiveRecord
end
end
- class LazyAttributeHash
+ class LazyAttributeHash # :nodoc:
delegate :select, :transform_values, to: :materialize
def initialize(types, values, additional_types)
@@ -35,11 +35,7 @@ module ActiveRecord
end
def [](key)
- if delegate_hash.key?(key)
- delegate_hash[key]
- else
- assign_default_value(key)
- end
+ delegate_hash[key] || assign_default_value(key)
end
def []=(key, value)
@@ -66,9 +62,11 @@ module ActiveRecord
def assign_default_value(name)
type = additional_types.fetch(name, types[name])
+ value_present = true
+ value = values.fetch(name) { value_present = false }
- if values.key?(name)
- delegate_hash[name] = Attribute.from_database(name, values[name], type)
+ if value_present
+ delegate_hash[name] = Attribute.from_database(name, value, type)
elsif types.key?(name)
delegate_hash[name] = Attribute.uninitialized(name, type)
end
diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb
index 5958373e88..f053372cfb 100644
--- a/activerecord/lib/active_record/enum.rb
+++ b/activerecord/lib/active_record/enum.rb
@@ -142,7 +142,7 @@ module ActiveRecord
private
def save_changed_attribute(attr_name, old)
if (mapping = self.class.defined_enums[attr_name.to_s])
- value = read_attribute(attr_name)
+ value = _read_attribute(attr_name)
if attribute_changed?(attr_name)
if mapping[old] == value
clear_attribute_changes([attr_name])
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 4b58f2deb7..f4a351b092 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -287,7 +287,7 @@ module ActiveRecord
def association_scope_cache(conn, owner)
key = conn.prepared_statements
if polymorphic?
- key = [key, owner.read_attribute(@foreign_type)]
+ key = [key, owner._read_attribute(@foreign_type)]
end
@association_scope_cache[key] ||= @scope_lock.synchronize {
@association_scope_cache[key] ||= yield
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 8575e5a7be..460daf99bc 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -639,7 +639,7 @@ module ActiveRecord
preload = preload_values
preload += includes_values unless eager_loading?
- preloader = ActiveRecord::Associations::Preloader.new
+ preloader = build_preloader
preload.each do |associations|
preloader.preload @records, associations
end
@@ -650,6 +650,10 @@ module ActiveRecord
@records
end
+ def build_preloader
+ ActiveRecord::Associations::Preloader.new
+ end
+
def references_eager_loaded_tables?
joined_tables = arel.join_sources.map do |join|
if join.is_a?(Arel::Nodes::StringJoin)
diff --git a/activerecord/lib/active_record/type/integer.rb b/activerecord/lib/active_record/type/integer.rb
index d69e5b3f28..36bbd9cd5e 100644
--- a/activerecord/lib/active_record/type/integer.rb
+++ b/activerecord/lib/active_record/type/integer.rb
@@ -14,6 +14,11 @@ module ActiveRecord
alias type_cast_for_database type_cast
+ def type_cast_from_database(value)
+ return if value.nil?
+ value.to_i
+ end
+
protected
attr_reader :range
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 2dba4c7b94..3e8afe37a8 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -79,7 +79,7 @@ module ActiveRecord
scope_value = record.send(reflection.foreign_key)
scope_item = reflection.foreign_key
else
- scope_value = record.read_attribute(scope_item)
+ scope_value = record._read_attribute(scope_item)
end
relation = relation.and(table[scope_item].eq(scope_value))
end
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index 792950d24d..0338669016 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -22,7 +22,7 @@ class InheritanceTest < ActiveRecord::TestCase
company = Company.first
company = company.dup
company.extend(Module.new {
- def read_attribute(name)
+ def _read_attribute(name)
return ' ' if name == 'type'
super
end
diff --git a/guides/source/3_0_release_notes.md b/guides/source/3_0_release_notes.md
index 46be2613ab..2630207c0f 100644
--- a/guides/source/3_0_release_notes.md
+++ b/guides/source/3_0_release_notes.md
@@ -298,7 +298,7 @@ Deprecations
More Information:
* [The Rails 3 Router: Rack it Up](http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/)
-* [Revamped Routes in Rails 3](http://rizwanreza.com/2009/12/20/revamped-routes-in-rails-3)
+* [Revamped Routes in Rails 3](https://medium.com/fusion-of-thoughts/revamped-routes-in-rails-3-b6d00654e5b0)
* [Generic Actions in Rails 3](http://yehudakatz.com/2009/12/20/generic-actions-in-rails-3/)