aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/CHANGELOG.md8
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb4
-rw-r--r--actionview/CHANGELOG.md3
-rw-r--r--actionview/test/template/date_helper_test.rb2
-rw-r--r--activemodel/CHANGELOG.md11
-rw-r--r--activemodel/lib/active_model/dirty.rb23
-rw-r--r--activemodel/test/cases/dirty_test.rb13
-rw-r--r--activerecord/CHANGELOG.md16
-rw-r--r--activerecord/lib/active_record/associations/builder/association.rb2
-rw-r--r--activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb2
-rw-r--r--activerecord/lib/active_record/reflection.rb4
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb4
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb8
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb16
-rw-r--r--activerecord/test/cases/autosave_association_test.rb2
-rw-r--r--activerecord/test/cases/fixtures_test.rb12
-rw-r--r--activesupport/CHANGELOG.md8
-rw-r--r--activesupport/lib/active_support/core_ext/module/aliasing.rb3
-rw-r--r--activesupport/lib/active_support/testing/isolation.rb8
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb63
-rw-r--r--activesupport/test/time_zone_test.rb74
-rw-r--r--guides/source/command_line.md2
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md33
-rw-r--r--guides/source/getting_started.md4
-rw-r--r--railties/CHANGELOG.md18
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb2
26 files changed, 257 insertions, 88 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index a5e551c78e..0a31e34d3d 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -35,11 +35,11 @@
*Kohei Suzuki*
-* Fix handling of empty X_FORWARDED_HOST header in raw_host_with_port
+* Fix handling of empty `X_FORWARDED_HOST` header in `raw_host_with_port`.
- Previously, an empty X_FORWARDED_HOST header would cause
- Actiondispatch::Http:URL.raw_host_with_port to return nil, causing
- Actiondispatch::Http:URL.host to raise a NoMethodError.
+ Previously, an empty `X_FORWARDED_HOST` header would cause
+ `Actiondispatch::Http:URL.raw_host_with_port` to return `nil`, causing
+ `Actiondispatch::Http:URL.host` to raise a `NoMethodError`.
*Adam Forsyth*
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index b7687ca100..b1f0f5fc28 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -482,8 +482,8 @@ module ActionDispatch
# UpgradeLegacySignedCookieJar is used instead of SignedCookieJar if
# secrets.secret_token and secrets.secret_key_base are both set. It reads
- # legacy cookies signed with the old dummy key generator and re-saves
- # them using the new key generator to provide a smooth upgrade path.
+ # legacy cookies signed with the old dummy key generator and signs and
+ # re-saves them using the new key generator to provide a smooth upgrade path.
class UpgradeLegacySignedCookieJar < SignedCookieJar #:nodoc:
include VerifyAndUpgradeLegacySignedMessage
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index 74dbff80da..78ce230b3a 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -14,8 +14,7 @@
*Adam Prescott*
* `translate` should accept nils as members of the `:default`
- parameter without raising a translation missing error. Fixes a
- regression introduced 362557e.
+ parameter without raising a translation missing error.
Fixes #19419
diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb
index bfb073680e..a0e1f5f3bb 100644
--- a/actionview/test/template/date_helper_test.rb
+++ b/actionview/test/template/date_helper_test.rb
@@ -130,7 +130,7 @@ class DateHelperTest < ActionView::TestCase
def test_distance_in_words_with_mathn_required
# test we avoid Integer#/ (redefined by mathn)
- require 'mathn'
+ silence_warnings { require "mathn" }
from = Time.utc(2004, 6, 6, 21, 45, 0)
assert_distance_of_time_in_words(from)
end
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index 32a2cb4517..4961d69d2a 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,3 +1,12 @@
+* Add `ActiveModel::Dirty#[attr_name]_previously_changed?` and
+ `ActiveModel::Dirty#[attr_name]_previous_change` to improve access
+ to recorded changes after the model has been saved.
+
+ It makes the dirty-attributes query methods consistent before and after
+ saving.
+
+ *Fernando Tapia Rico*
+
* Deprecate the `:tokenizer` option for `validates_length_of`, in favor of
plain Ruby.
@@ -13,7 +22,7 @@
*Wojciech Wnętrzak*
-* Allow symbol as values for `tokenize` of `LengthValidator`
+* Allow symbol as values for `tokenize` of `LengthValidator`.
*Kensuke Naito*
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb
index c03e5fac79..c0fc507286 100644
--- a/activemodel/lib/active_model/dirty.rb
+++ b/activemodel/lib/active_model/dirty.rb
@@ -76,9 +76,11 @@ module ActiveModel
#
# Reset the changes:
#
- # person.previous_changes # => {"name" => ["Uncle Bob", "Bill"]}
+ # person.previous_changes # => {"name" => ["Uncle Bob", "Bill"]}
+ # person.name_previously_changed? # => true
+ # person.name_previous_change # => ["Uncle Bob", "Bill"]
# person.reload!
- # person.previous_changes # => {}
+ # person.previous_changes # => {}
#
# Rollback the changes:
#
@@ -115,6 +117,7 @@ module ActiveModel
included do
attribute_method_suffix '_changed?', '_change', '_will_change!', '_was'
+ attribute_method_suffix '_previously_changed?', '_previous_change'
attribute_method_affix prefix: 'restore_', suffix: '!'
end
@@ -179,6 +182,11 @@ module ActiveModel
attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
end
+ # Handles <tt>*_previously_changed?</tt> for +method_missing+.
+ def attribute_previously_changed?(attr, options = {}) #:nodoc:
+ previous_changes_include?(attr)
+ end
+
# Restore all previous data of the provided attributes.
def restore_attributes(attributes = changed)
attributes.each { |attr| restore_attribute! attr }
@@ -192,6 +200,12 @@ module ActiveModel
end
alias attribute_changed_by_setter? changes_include?
+ # Returns +true+ if attr_name were changed before the model was saved,
+ # +false+ otherwise.
+ def previous_changes_include?(attr_name)
+ @previously_changed.include?(attr_name)
+ end
+
# Removes current changes and makes them accessible through +previous_changes+.
def changes_applied # :doc:
@previously_changed = changes
@@ -209,6 +223,11 @@ module ActiveModel
[changed_attributes[attr], __send__(attr)] if attribute_changed?(attr)
end
+ # Handles <tt>*_previous_change</tt> for +method_missing+.
+ def attribute_previous_change(attr)
+ @previously_changed[attr] if attribute_previously_changed?(attr)
+ end
+
# Handles <tt>*_will_change!</tt> for +method_missing+.
def attribute_will_change!(attr)
return if attribute_changed?(attr)
diff --git a/activemodel/test/cases/dirty_test.rb b/activemodel/test/cases/dirty_test.rb
index 66ed8a350a..d17a12ad12 100644
--- a/activemodel/test/cases/dirty_test.rb
+++ b/activemodel/test/cases/dirty_test.rb
@@ -137,6 +137,19 @@ class DirtyTest < ActiveModel::TestCase
assert_equal [nil, "Jericho Cane"], @model.previous_changes['name']
end
+ test "setting new attributes should not affect previous changes" do
+ @model.name = "Jericho Cane"
+ @model.save
+ @model.name = "DudeFella ManGuy"
+ assert_equal [nil, "Jericho Cane"], @model.name_previous_change
+ end
+
+ test "saving should preserve model's previous changed status" do
+ @model.name = "Jericho Cane"
+ @model.save
+ assert @model.name_previously_changed?
+ end
+
test "previous value is preserved when changed after save" do
assert_equal({}, @model.changed_attributes)
@model.name = "Paul"
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 58ebd5d9ed..319ccaec3a 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,9 @@
+* Rename `:class` to `:anonymous_class` in association options.
+
+ Fixes #19659.
+
+ *Andrew White*
+
* Autosave existing records on a has many through association when the parent
is new.
@@ -28,20 +34,22 @@
*Mehmet Emin İNAÇ*
-* Reduce memory usage from loading types on pg.
+* Reduce memory usage from loading types on PostgreSQL.
Fixes #19578.
*Sean Griffin*
-* Add `config.active_record.warn_on_records_fetched_greater_than` option
+* Add `config.active_record.warn_on_records_fetched_greater_than` option.
When set to an integer, a warning will be logged whenever a result set
- larger than the specified size is returned by a query. Fixes #16463
+ larger than the specified size is returned by a query.
+
+ Fixes #16463.
*Jason Nochlin*
-* Ignore psqlrc when loading database structure.
+* Ignore `.psqlrc` when loading database structure.
*Jason Weathered*
diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb
index 88406740d8..ba1b1814d1 100644
--- a/activerecord/lib/active_record/associations/builder/association.rb
+++ b/activerecord/lib/active_record/associations/builder/association.rb
@@ -16,7 +16,7 @@ module ActiveRecord::Associations::Builder
end
self.extensions = []
- VALID_OPTIONS = [:class_name, :class, :foreign_key, :validate] # :nodoc:
+ VALID_OPTIONS = [:class_name, :anonymous_class, :foreign_key, :validate] # :nodoc:
def self.build(model, name, scope, options, &block)
if model.dangerous_attribute_method?(name)
diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
index 97b57a6a55..ffd9c9d6fc 100644
--- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
+++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
@@ -78,7 +78,7 @@ module ActiveRecord::Associations::Builder
join_model.table_name_resolver = habtm
join_model.class_resolver = lhs_model
- join_model.add_left_association :left_side, class: lhs_model
+ join_model.add_left_association :left_side, anonymous_class: lhs_model
join_model.add_right_association association_name, belongs_to_options(options)
join_model
end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 4265afc0a5..1b0ae2c942 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -196,7 +196,7 @@ module ActiveRecord
@scope = scope
@options = options
@active_record = active_record
- @klass = options[:class]
+ @klass = options[:anonymous_class]
@plural_name = active_record.pluralize_table_names ?
name.to_s.pluralize : name.to_s
end
@@ -635,7 +635,7 @@ module ActiveRecord
def initialize(delegate_reflection)
@delegate_reflection = delegate_reflection
- @klass = delegate_reflection.options[:class]
+ @klass = delegate_reflection.options[:anonymous_class]
@source_reflection_name = delegate_reflection.options[:source]
end
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index 95d00ab3a9..ba90c61d65 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -124,9 +124,9 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
where("id = :inc", :inc => counter)
}
- has_many :comments, :class => comments
+ has_many :comments, :anonymous_class => comments
}
- belongs_to :post, :class => posts, :inverse_of => false
+ belongs_to :post, :anonymous_class => posts, :inverse_of => false
}
assert_equal 0, counter
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 171cfbde44..14cdf37f46 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -119,9 +119,9 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
developer_project = Class.new(ActiveRecord::Base) {
self.table_name = 'developers_projects'
- belongs_to :developer, :class => dev
+ belongs_to :developer, :anonymous_class => dev
}
- has_many :developer_projects, :class => developer_project, :foreign_key => 'developer_id'
+ has_many :developer_projects, :anonymous_class => developer_project, :foreign_key => 'developer_id'
}
dev = developer.first
named = Developer.find(dev.id)
@@ -140,13 +140,13 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
comments = Class.new(ActiveRecord::Base) {
self.table_name = 'comments'
self.inheritance_column = 'not_there'
- belongs_to :post, :class => post
+ belongs_to :post, :anonymous_class => post
default_scope -> {
counter += 1
where("id = :inc", :inc => counter)
}
}
- has_many :comments, :class => comments, :foreign_key => 'post_id'
+ has_many :comments, :anonymous_class => comments, :foreign_key => 'post_id'
}
assert_equal 0, counter
post = posts.first
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index 5f52c65412..9734ea2217 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -84,11 +84,11 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
subscriber = make_model "Subscriber"
subscriber.primary_key = 'nick'
- subscription.belongs_to :book, class: book
- subscription.belongs_to :subscriber, class: subscriber
+ subscription.belongs_to :book, anonymous_class: book
+ subscription.belongs_to :subscriber, anonymous_class: subscriber
- book.has_many :subscriptions, class: subscription
- book.has_many :subscribers, through: :subscriptions, class: subscriber
+ book.has_many :subscriptions, anonymous_class: subscription
+ book.has_many :subscribers, through: :subscriptions, anonymous_class: subscriber
anonbook = book.first
namebook = Book.find anonbook.id
@@ -154,10 +154,10 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
lesson_student = make_model 'LessonStudent'
lesson_student.table_name = 'lessons_students'
- lesson_student.belongs_to :lesson, :class => lesson
- lesson_student.belongs_to :student, :class => student
- lesson.has_many :lesson_students, :class => lesson_student
- lesson.has_many :students, :through => :lesson_students, :class => student
+ lesson_student.belongs_to :lesson, :anonymous_class => lesson
+ lesson_student.belongs_to :student, :anonymous_class => student
+ lesson.has_many :lesson_students, :anonymous_class => lesson_student
+ lesson.has_many :students, :through => :lesson_students, :anonymous_class => student
[lesson, lesson_student, student]
end
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index 0e6f38cad6..80b5a0004d 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -43,7 +43,7 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
reference = Class.new(ActiveRecord::Base) {
self.table_name = "references"
def self.name; 'Reference'; end
- belongs_to :person, autosave: true, class: person
+ belongs_to :person, autosave: true, anonymous_class: person
}
u = person.create!(first_name: 'cool')
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index f8acdcb51e..97ba178b4d 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -279,10 +279,10 @@ class HasManyThroughFixture < ActiveSupport::TestCase
treasure = make_model "Treasure"
pt.table_name = "parrots_treasures"
- pt.belongs_to :parrot, :class => parrot
- pt.belongs_to :treasure, :class => treasure
+ pt.belongs_to :parrot, :anonymous_class => parrot
+ pt.belongs_to :treasure, :anonymous_class => treasure
- parrot.has_many :parrot_treasures, :class => pt
+ parrot.has_many :parrot_treasures, :anonymous_class => pt
parrot.has_many :treasures, :through => :parrot_treasures
parrots = File.join FIXTURES_ROOT, 'parrots'
@@ -297,10 +297,10 @@ class HasManyThroughFixture < ActiveSupport::TestCase
parrot = make_model "Parrot"
treasure = make_model "Treasure"
- pt.belongs_to :parrot, :class => parrot
- pt.belongs_to :treasure, :class => treasure
+ pt.belongs_to :parrot, :anonymous_class => parrot
+ pt.belongs_to :treasure, :anonymous_class => treasure
- parrot.has_many :parrot_treasures, :class => pt
+ parrot.has_many :parrot_treasures, :anonymous_class => pt
parrot.has_many :treasures, :through => :parrot_treasures
parrots = File.join FIXTURES_ROOT, 'parrots'
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 3ad2392365..b1c303e435 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Added `ActiveSupport::TimeZone#strptime` to allow parsing times as if
+ from a given timezone.
+
+ *Paul A Jungwirth*
+
* `ActiveSupport::Callbacks#skip_callback` now raises an `ArgumentError` if
an unrecognized callback is removed.
@@ -23,7 +28,8 @@
*George Claghorn*
-* Deprecate `alias_method_chain` in favour of `Module#prepend` introduced in Ruby 2.0
+* Deprecate `alias_method_chain` in favour of `Module#prepend` introduced in
+ Ruby 2.0.
*Kir Shatrov*
diff --git a/activesupport/lib/active_support/core_ext/module/aliasing.rb b/activesupport/lib/active_support/core_ext/module/aliasing.rb
index a4c40b25ff..b6934b9c54 100644
--- a/activesupport/lib/active_support/core_ext/module/aliasing.rb
+++ b/activesupport/lib/active_support/core_ext/module/aliasing.rb
@@ -1,4 +1,7 @@
class Module
+ # NOTE: This method is deprecated. Please use <tt>Module#prepend</tt> that
+ # comes with Ruby 2.0 or newer instead.
+ #
# Encapsulates the common pattern of:
#
# alias_method :foo_without_feature, :foo
diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb
index 247df7423b..1de0a19998 100644
--- a/activesupport/lib/active_support/testing/isolation.rb
+++ b/activesupport/lib/active_support/testing/isolation.rb
@@ -69,17 +69,17 @@ module ActiveSupport
else
Tempfile.open("isolation") do |tmpfile|
env = {
- ISOLATION_TEST: self.class.name,
- ISOLATION_OUTPUT: tmpfile.path
+ 'ISOLATION_TEST' => self.class.name,
+ 'ISOLATION_OUTPUT' => tmpfile.path
}
load_paths = $-I.map {|p| "-I\"#{File.expand_path(p)}\"" }.join(" ")
orig_args = ORIG_ARGV.join(" ")
test_opts = "-n#{self.class.name}##{self.name}"
- command = "#{Gem.ruby} #{load_paths} #{$0} #{orig_args} #{test_opts}"
+ command = "#{Gem.ruby} #{load_paths} #{$0} '#{orig_args}' #{test_opts}"
# IO.popen lets us pass env in a cross-platform way
- child = IO.popen([env, command])
+ child = IO.popen(env, command)
begin
Process.wait(child.pid)
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index da39f0d245..2b59c7a33d 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -348,24 +348,31 @@ module ActiveSupport
#
# Time.zone.parse('Mar 2000') # => Wed, 01 Mar 2000 00:00:00 HST -10:00
def parse(str, now=now())
- parts = Date._parse(str, false)
- return if parts.empty?
-
- time = Time.new(
- parts.fetch(:year, now.year),
- parts.fetch(:mon, now.month),
- parts.fetch(:mday, parts[:year] || parts[:mon] ? 1 : now.day),
- parts.fetch(:hour, 0),
- parts.fetch(:min, 0),
- parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
- parts.fetch(:offset, 0)
- )
-
- if parts[:offset]
- TimeWithZone.new(time.utc, self)
- else
- TimeWithZone.new(nil, self, time)
- end
+ parts_to_time(Date._parse(str, false), now)
+ end
+
+ # Parses +str+ according to +format+ and returns an ActiveSupport::TimeWithZone.
+ #
+ # Assumes that +str+ is a time in the time zone +self+,
+ # unless +format+ includes an explicit time zone.
+ # (This is the same behavior as +parse+.)
+ # In either case, the returned TimeWithZone has the timezone of +self+.
+ #
+ # Time.zone = 'Hawaii' # => "Hawaii"
+ # Time.zone.strptime('1999-12-31 14:00:00', '%Y-%m-%d %H:%M:%S') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+ #
+ # If upper components are missing from the string, they are supplied from
+ # TimeZone#now:
+ #
+ # Time.zone.now # => Fri, 31 Dec 1999 14:00:00 HST -10:00
+ # Time.zone.strptime('22:30:00', '%H:%M:%S') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
+ #
+ # However, if the date component is not provided, but any other upper
+ # components are supplied, then the day of the month defaults to 1:
+ #
+ # Time.zone.strptime('Mar 2000', '%b %Y') # => Wed, 01 Mar 2000 00:00:00 HST -10:00
+ def strptime(str, format, now=now())
+ parts_to_time(DateTime._strptime(str, format), now)
end
# Returns an ActiveSupport::TimeWithZone instance representing the current
@@ -422,6 +429,26 @@ module ActiveSupport
end
private
+ def parts_to_time(parts, now)
+ return if parts.empty?
+
+ time = Time.new(
+ parts.fetch(:year, now.year),
+ parts.fetch(:mon, now.month),
+ parts.fetch(:mday, parts[:year] || parts[:mon] ? 1 : now.day),
+ parts.fetch(:hour, 0),
+ parts.fetch(:min, 0),
+ parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
+ parts.fetch(:offset, 0)
+ )
+
+ if parts[:offset]
+ TimeWithZone.new(time.utc, self)
+ else
+ TimeWithZone.new(nil, self, time)
+ end
+ end
+
def time_now
Time.now
end
diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb
index 7888b9919b..ea90caa143 100644
--- a/activesupport/test/time_zone_test.rb
+++ b/activesupport/test/time_zone_test.rb
@@ -311,6 +311,80 @@ class TimeZoneTest < ActiveSupport::TestCase
end
end
+ def test_strptime
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ twz = zone.strptime('1999-12-31 12:00:00', '%Y-%m-%d %H:%M:%S')
+ assert_equal Time.utc(1999,12,31,17), twz
+ assert_equal Time.utc(1999,12,31,12), twz.time
+ assert_equal Time.utc(1999,12,31,17), twz.utc
+ assert_equal zone, twz.time_zone
+ end
+
+ def test_strptime_with_nondefault_time_zone
+ with_tz_default ActiveSupport::TimeZone['Pacific Time (US & Canada)'] do
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ twz = zone.strptime('1999-12-31 12:00:00', '%Y-%m-%d %H:%M:%S')
+ assert_equal Time.utc(1999,12,31,17), twz
+ assert_equal Time.utc(1999,12,31,12), twz.time
+ assert_equal Time.utc(1999,12,31,17), twz.utc
+ assert_equal zone, twz.time_zone
+ end
+ end
+
+ def test_strptime_with_explicit_time_zone_as_abbrev
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ twz = zone.strptime('1999-12-31 12:00:00 PST', '%Y-%m-%d %H:%M:%S %Z')
+ assert_equal Time.utc(1999,12,31,20), twz
+ assert_equal Time.utc(1999,12,31,15), twz.time
+ assert_equal Time.utc(1999,12,31,20), twz.utc
+ assert_equal zone, twz.time_zone
+ end
+
+ def test_strptime_with_explicit_time_zone_as_h_offset
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ twz = zone.strptime('1999-12-31 12:00:00 -08', '%Y-%m-%d %H:%M:%S %:::z')
+ assert_equal Time.utc(1999,12,31,20), twz
+ assert_equal Time.utc(1999,12,31,15), twz.time
+ assert_equal Time.utc(1999,12,31,20), twz.utc
+ assert_equal zone, twz.time_zone
+ end
+
+ def test_strptime_with_explicit_time_zone_as_hm_offset
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ twz = zone.strptime('1999-12-31 12:00:00 -08:00', '%Y-%m-%d %H:%M:%S %:z')
+ assert_equal Time.utc(1999,12,31,20), twz
+ assert_equal Time.utc(1999,12,31,15), twz.time
+ assert_equal Time.utc(1999,12,31,20), twz.utc
+ assert_equal zone, twz.time_zone
+ end
+
+ def test_strptime_with_explicit_time_zone_as_hms_offset
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ twz = zone.strptime('1999-12-31 12:00:00 -08:00:00', '%Y-%m-%d %H:%M:%S %::z')
+ assert_equal Time.utc(1999,12,31,20), twz
+ assert_equal Time.utc(1999,12,31,15), twz.time
+ assert_equal Time.utc(1999,12,31,20), twz.utc
+ assert_equal zone, twz.time_zone
+ end
+
+ def test_strptime_with_almost_explicit_time_zone
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ twz = zone.strptime('1999-12-31 12:00:00 %Z', '%Y-%m-%d %H:%M:%S %%Z')
+ assert_equal Time.utc(1999,12,31,17), twz
+ assert_equal Time.utc(1999,12,31,12), twz.time
+ assert_equal Time.utc(1999,12,31,17), twz.utc
+ assert_equal zone, twz.time_zone
+ end
+
+ def test_strptime_with_day_omitted
+ with_env_tz 'US/Eastern' do
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ assert_equal Time.local(2000, 2, 1), zone.strptime('Feb', '%b', Time.local(2000, 1, 1))
+ assert_equal Time.local(2005, 2, 1), zone.strptime('Feb 2005', '%b %Y', Time.local(2000, 1, 1))
+ assert_equal Time.local(2005, 2, 2), zone.strptime('2 Feb 2005', '%e %b %Y', Time.local(2000, 1, 1))
+ end
+ end
+
def test_utc_offset_lazy_loaded_from_tzinfo_when_not_passed_in_to_initialize
tzinfo = TZInfo::Timezone.get('America/New_York')
zone = ActiveSupport::TimeZone.create(tzinfo.name, nil, tzinfo)
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index 8f9102611d..315d8c14b6 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -423,7 +423,7 @@ If you want to clear `public/assets` completely, you can use `rake assets:clobbe
The most common tasks of the `db:` Rake namespace are `migrate` and `create`, and it will pay off to try out all of the migration rake tasks (`up`, `down`, `redo`, `reset`). `rake db:version` is useful when troubleshooting, telling you the current version of the database.
-More information about migrations can be found in the [Migrations](migrations.html) guide.
+More information about migrations can be found in the [Migrations](active_record_migrations.html) guide.
### `notes`
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index 7778b6c5e0..3d5f8906ca 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -403,21 +403,27 @@ When you're happy with the code on your computer, you need to commit the changes
$ git commit -a
```
-At this point, your editor should be fired up and you can write a message for this commit. Well formatted and descriptive commit messages are extremely helpful for the others, especially when figuring out why given change was made, so please take the time to write it.
+This should fire up your editor to write a commit message. When you have
+finished, save and close to continue.
-Good commit message should be formatted according to the following example:
+A well-formatted and descriptive commit message is very helpful to others for
+understanding why the change was made, so please take the time to write it.
+
+A good commit message looks like this:
```
Short summary (ideally 50 characters or less)
-More detailed description, if necessary. It should be wrapped to 72
-characters. Try to be as descriptive as you can; even if you think that the
-commit content is obvious, it may not be obvious to others. Add any description
-that is already present in relevant issues - it should not be necessary to visit
-a webpage to check the history.
+More detailed description, if necessary. It should be wrapped to
+72 characters. Try to be as descriptive as you can. Even if you
+think that the commit content is obvious, it may not be obvious
+to others. Add any description that is already present in the
+relevant issues; it should not be necessary to visit a webpage
+to check the history.
+
+The description section can have multiple paragraphs.
-The description section can have multiple paragraphs. Code examples can be
-embedded by indenting them with 4 spaces:
+Code examples can be embedded by indenting them with 4 spaces:
class ArticlesController
def index
@@ -427,14 +433,15 @@ embedded by indenting them with 4 spaces:
You can also add bullet points:
-- you can use dashes or asterisks
+- make a bullet point by starting a line with either a dash (-)
+ or an asterisk (*)
-- also, try to indent next line of a point for readability, if it's too
- long to fit in 72 characters
+- wrap lines at 72 characters, and indent any additional lines
+ with 2 spaces for readability
```
TIP. Please squash your commits into a single commit when appropriate. This
-simplifies future cherry picks and also keeps the git log clean.
+simplifies future cherry picks and keeps the git log clean.
### Update Your Branch
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index 7a23f0802e..684a53e472 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -23,7 +23,7 @@ application from scratch. It does not assume that you have any prior experience
with Rails. However, to get the most out of it, you need to have some
prerequisites installed:
-* The [Ruby](https://www.ruby-lang.org/en/downloads) language version 1.9.3 or newer.
+* The [Ruby](https://www.ruby-lang.org/en/downloads) language version 2.2.2 or newer.
* The [RubyGems](https://rubygems.org) packaging system, which is installed with Ruby
versions 1.9 and later. To learn more about RubyGems, please read the [RubyGems Guides](http://guides.rubygems.org).
* A working installation of the [SQLite3 Database](https://www.sqlite.org).
@@ -97,7 +97,7 @@ For more installation methods for most Operating Systems take a look at
```bash
$ ruby -v
-ruby 2.0.0p353
+ruby 2.2.2p95
```
Many popular UNIX-like OSes ship with an acceptable version of SQLite3.
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 6193c33593..ff9694b6ca 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,4 +1,5 @@
-* Rename `railties/bin` to `railties/exe` to match the new Bundler executables convention.
+* Rename `railties/bin` to `railties/exe` to match the new Bundler executables
+ convention.
*Islam Wazery*
@@ -22,7 +23,7 @@
*arthurnn*
-* Add `rake initializers`
+* Add `rake initializers`.
This task prints out all defined initializers in the order they are invoked
by Rails. This is helpful for debugging issues related to the initialization
@@ -37,7 +38,7 @@
*Hyonjee Joo*
-* Add `config/initializers/active_record_belongs_to_required_by_default.rb`
+* Add `config/initializers/active_record_belongs_to_required_by_default.rb`.
Newly generated Rails apps have a new initializer called
`active_record_belongs_to_required_by_default.rb` which sets the value of
@@ -56,7 +57,7 @@
'No such middleware' errors when `insert_before` or `insert_after` are added
after the `delete` operation for the middleware being deleted.
- Fixes: #16433.
+ Fixes #16433.
*Guo Xiang Tan*
@@ -68,7 +69,7 @@
*Xavier Noria*
-* Force generated routes to be inserted into routes.rb
+* Force generated routes to be inserted into `config/routes.rb`.
*Andrew White*
@@ -82,11 +83,12 @@
*Melanie Gilman*
-* Add the `method_source` gem to the default Gemfile for apps
+* Add the `method_source` gem to the default Gemfile for apps.
*Sean Griffin*
-* Drop old test locations from `rake stats`
+* Drop old test locations from `rake stats`:
+
- test/functional
- test/unit
@@ -117,7 +119,7 @@
*Andrew Kozlov*
-* Add `config/initializers/callback_terminator.rb`
+* Add `config/initializers/callback_terminator.rb`.
Newly generated Rails apps have a new initializer called
`callback_terminator.rb` which sets the value of the configuration option
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
index d9713b0238..d99b27cb2d 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
@@ -17,6 +17,7 @@
<%%= f.label :password %><br>
<%%= f.password_field :password %>
</div>
+
<div class="field">
<%%= f.label :password_confirmation %><br>
<%%= f.password_field :password_confirmation %>
@@ -25,6 +26,7 @@
<%%= f.<%= attribute.field_type %> :<%= attribute.column_name %> %>
<% end -%>
</div>
+
<% end -%>
<div class="actions">
<%%= f.submit %>