aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.lock2
-rw-r--r--actionview/test/template/date_helper_test.rb14
-rw-r--r--activemodel/lib/active_model/attribute_assignment.rb4
-rw-r--r--activerecord/lib/active_record/associations/alias_tracker.rb7
-rw-r--r--activerecord/lib/active_record/associations/preloader/association.rb7
-rw-r--r--activerecord/lib/active_record/associations/preloader/belongs_to.rb2
-rw-r--r--activerecord/lib/active_record/associations/preloader/through_association.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb10
-rw-r--r--activerecord/lib/active_record/querying.rb2
-rw-r--r--activerecord/lib/active_record/reflection.rb36
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb7
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb7
-rw-r--r--activerecord/lib/active_record/scoping/default.rb6
-rw-r--r--activerecord/lib/active_record/tasks/sqlite_database_tasks.rb2
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb13
-rw-r--r--activerecord/test/cases/base_test.rb74
-rw-r--r--activerecord/test/cases/calculations_test.rb9
-rw-r--r--activerecord/test/cases/dirty_test.rb5
-rw-r--r--activerecord/test/cases/inheritance_test.rb7
-rw-r--r--activerecord/test/cases/numeric_data_test.rb71
-rw-r--r--activerecord/test/cases/scoping/named_scoping_test.rb6
-rw-r--r--activerecord/test/models/comment.rb2
-rw-r--r--activerecord/test/models/numeric_data.rb8
-rw-r--r--activesupport/CHANGELOG.md4
-rw-r--r--activesupport/lib/active_support/core_ext/date_and_time/calculations.rb16
-rw-r--r--activesupport/test/core_ext/date_time_ext_test.rb22
-rw-r--r--guides/source/asset_pipeline.md2
-rw-r--r--guides/source/getting_started.md2
-rw-r--r--railties/lib/rails/generators/app_base.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt7
-rw-r--r--railties/test/generators/app_generator_test.rb2
32 files changed, 213 insertions, 151 deletions
diff --git a/Gemfile b/Gemfile
index 8260533cb5..2a1b9fa7ef 100644
--- a/Gemfile
+++ b/Gemfile
@@ -154,7 +154,3 @@ end
gem "ibm_db" if ENV["IBM_DB"]
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem "wdm", ">= 0.1.0", platforms: [:mingw, :mswin, :x64_mingw, :mswin64]
-
-platforms :ruby_25 do
- gem "mathn"
-end
diff --git a/Gemfile.lock b/Gemfile.lock
index e6640a116b..d08ddaf1b4 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -209,7 +209,6 @@ GEM
nokogiri (>= 1.5.9)
mail (2.6.5)
mime-types (>= 1.16, < 4)
- mathn (0.1.0)
metaclass (0.0.4)
method_source (0.8.2)
mime-types (3.1)
@@ -400,7 +399,6 @@ DEPENDENCIES
kindlerb (~> 1.2.0)
libxml-ruby
listen (>= 3.0.5, < 3.2)
- mathn
minitest (< 5.3.4)
mocha (~> 0.14)
mysql2 (>= 0.4.4)
diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb
index a259752d6a..b667303318 100644
--- a/actionview/test/template/date_helper_test.rb
+++ b/actionview/test/template/date_helper_test.rb
@@ -138,11 +138,19 @@ class DateHelperTest < ActionView::TestCase
assert_equal "10 minutes", distance_of_time_in_words(Time.at(600), 0)
end
- def test_distance_in_words_with_mathn_required
- # test we avoid Integer#/ (redefined by mathn)
- silence_warnings { require "mathn" }
+ def test_distance_in_words_doesnt_use_the_quotient_operator
+ rubinius_skip "Date is written in Ruby and relies on Fixnum#/"
+ jruby_skip "Date is written in Ruby and relies on Fixnum#/"
+
+ klass = RUBY_VERSION > "2.4" ? Integer : Fixnum
+
+ # Make sure that we avoid {Integer,Fixnum}#/ (redefined by mathn)
+ klass.send :private, :/
+
from = Time.utc(2004, 6, 6, 21, 45, 0)
assert_distance_of_time_in_words(from)
+ ensure
+ klass.send :public, :/
end
def test_time_ago_in_words_passes_include_seconds
diff --git a/activemodel/lib/active_model/attribute_assignment.rb b/activemodel/lib/active_model/attribute_assignment.rb
index ee130df989..930e89d611 100644
--- a/activemodel/lib/active_model/attribute_assignment.rb
+++ b/activemodel/lib/active_model/attribute_assignment.rb
@@ -19,10 +19,10 @@ module ActiveModel
# cat = Cat.new
# cat.assign_attributes(name: "Gorby", status: "yawning")
# cat.name # => 'Gorby'
- # cat.status => 'yawning'
+ # cat.status # => 'yawning'
# cat.assign_attributes(status: "sleeping")
# cat.name # => 'Gorby'
- # cat.status => 'sleeping'
+ # cat.status # => 'sleeping'
def assign_attributes(new_attributes)
if !new_attributes.respond_to?(:stringify_keys)
raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
diff --git a/activerecord/lib/active_record/associations/alias_tracker.rb b/activerecord/lib/active_record/associations/alias_tracker.rb
index 3963008a76..4a5c821607 100644
--- a/activerecord/lib/active_record/associations/alias_tracker.rb
+++ b/activerecord/lib/active_record/associations/alias_tracker.rb
@@ -4,8 +4,6 @@ module ActiveRecord
module Associations
# Keeps track of table aliases for ActiveRecord::Associations::JoinDependency
class AliasTracker # :nodoc:
- attr_reader :aliases
-
def self.create(connection, initial_table, type_caster)
aliases = Hash.new(0)
aliases[initial_table] = 1
@@ -80,6 +78,11 @@ module ActiveRecord
end
end
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
+ # Workaround for Ruby 2.2 "private attribute?" warning.
+ protected
+ attr_reader :aliases
+
private
def truncate(name)
diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb
index 4072d19380..63ef3f2d8c 100644
--- a/activerecord/lib/active_record/associations/preloader/association.rb
+++ b/activerecord/lib/active_record/associations/preloader/association.rb
@@ -51,11 +51,10 @@ module ActiveRecord
raise NotImplementedError
end
- def options
- reflection.options
- end
-
private
+ def options
+ reflection.options
+ end
def associated_records_by_owner(preloader)
records = load_records do |record|
diff --git a/activerecord/lib/active_record/associations/preloader/belongs_to.rb b/activerecord/lib/active_record/associations/preloader/belongs_to.rb
index 38e231826c..c20145770f 100644
--- a/activerecord/lib/active_record/associations/preloader/belongs_to.rb
+++ b/activerecord/lib/active_record/associations/preloader/belongs_to.rb
@@ -3,7 +3,7 @@ module ActiveRecord
class Preloader
class BelongsTo < SingularAssociation #:nodoc:
def association_key_name
- reflection.options[:primary_key] || klass && klass.primary_key
+ options[:primary_key] || klass && klass.primary_key
end
def owner_key_name
diff --git a/activerecord/lib/active_record/associations/preloader/through_association.rb b/activerecord/lib/active_record/associations/preloader/through_association.rb
index d53d3f777b..8b954138cd 100644
--- a/activerecord/lib/active_record/associations/preloader/through_association.rb
+++ b/activerecord/lib/active_record/associations/preloader/through_association.rb
@@ -65,7 +65,7 @@ module ActiveRecord
def reset_association(owners, association_name)
should_reset = (through_scope != through_reflection.klass.unscoped) ||
- (reflection.options[:source_type] && through_reflection.collection?)
+ (options[:source_type] && through_reflection.collection?)
# Don't cache the association - we would only be caching a subset
if should_reset
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 55566f1e34..cb45d7ba6b 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -290,9 +290,17 @@ module ActiveRecord
if pk && sequence
quoted_sequence = quote_table_name(sequence)
+ max_pk = select_value("select MAX(#{quote_column_name pk}) from #{quote_table_name(table)}")
+ if max_pk.nil?
+ if postgresql_version >= 100000
+ minvalue = select_value("SELECT seqmin from pg_sequence where seqrelid = '#{quoted_sequence}'::regclass")
+ else
+ minvalue = select_value("SELECT min_value FROM #{quoted_sequence}")
+ end
+ end
select_value(<<-end_sql, "SCHEMA")
- SELECT setval('#{quoted_sequence}', (SELECT COALESCE(MAX(#{quote_column_name pk})+(SELECT increment_by FROM #{quoted_sequence}), (SELECT min_value FROM #{quoted_sequence})) FROM #{quote_table_name(table)}), false)
+ SELECT setval('#{quoted_sequence}', #{max_pk ? max_pk : minvalue}, #{max_pk ? true : false})
end_sql
end
end
diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb
index c4a22398f0..b16e178358 100644
--- a/activerecord/lib/active_record/querying.rb
+++ b/activerecord/lib/active_record/querying.rb
@@ -8,7 +8,7 @@ module ActiveRecord
delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, to: :all
delegate :find_each, :find_in_batches, :in_batches, to: :all
delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
- :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly,
+ :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
:having, :create_with, :distinct, :references, :none, :unscope, :merge, to: :all
delegate :count, :average, :minimum, :maximum, :sum, :calculate, to: :all
delegate :pluck, :ids, to: :all
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 429f9a257a..e8ee8279fd 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -287,6 +287,11 @@ module ActiveRecord
JoinKeys.new(join_pk(association_klass), join_fk)
end
+ protected
+ def actual_source_reflection # FIXME: this is a horrible name
+ self
+ end
+
private
def join_pk(_)
@@ -583,12 +588,6 @@ module ActiveRecord
Array(options[:extend])
end
- protected
-
- def actual_source_reflection # FIXME: this is a horrible name
- self
- end
-
private
def calculate_constructable(macro, options)
@@ -761,7 +760,6 @@ module ActiveRecord
# Holds all the metadata about a :through association as it was specified
# in the Active Record class.
class ThroughReflection < AbstractReflection #:nodoc:
- attr_reader :delegate_reflection
delegate :foreign_key, :foreign_type, :association_foreign_key,
:active_record_primary_key, :type, :get_join_keys, to: :source_reflection
@@ -987,19 +985,23 @@ module ActiveRecord
collect_join_reflections(seed + [self])
end
- def collect_join_reflections(seed)
- a = source_reflection.add_as_source seed
- if options[:source_type]
- through_reflection.add_as_polymorphic_through self, a
- else
- through_reflection.add_as_through a
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
+ # Workaround for Ruby 2.2 "private attribute?" warning.
+ protected
+ attr_reader :delegate_reflection
+
+ def actual_source_reflection # FIXME: this is a horrible name
+ source_reflection.actual_source_reflection
end
- end
private
-
- def actual_source_reflection # FIXME: this is a horrible name
- source_reflection.send(:actual_source_reflection)
+ def collect_join_reflections(seed)
+ a = source_reflection.add_as_source seed
+ if options[:source_type]
+ through_reflection.add_as_polymorphic_through self, a
+ else
+ through_reflection.add_as_through a
+ end
end
def primary_key(klass)
diff --git a/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb b/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb
index 2fe0f81cab..3e19646ae5 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb
@@ -1,8 +1,6 @@
module ActiveRecord
class PredicateBuilder
class AssociationQueryValue # :nodoc:
- attr_reader :associated_table, :value
-
def initialize(associated_table, value)
@associated_table = associated_table
@value = value
@@ -12,6 +10,11 @@ module ActiveRecord
[associated_table.association_foreign_key.to_s => ids]
end
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
+ # Workaround for Ruby 2.2 "private attribute?" warning.
+ protected
+ attr_reader :associated_table, :value
+
private
def ids
case value
diff --git a/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb
index 9bb2f8c8dc..7029ae5f47 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb
@@ -1,8 +1,6 @@
module ActiveRecord
class PredicateBuilder
class PolymorphicArrayValue # :nodoc:
- attr_reader :associated_table, :values
-
def initialize(associated_table, values)
@associated_table = associated_table
@values = values
@@ -17,6 +15,11 @@ module ActiveRecord
end
end
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
+ # Workaround for Ruby 2.2 "private attribute?" warning.
+ protected
+ attr_reader :associated_table, :values
+
private
def type_to_ids_mapping
default_hash = Hash.new { |hsh, key| hsh[key] = [] }
diff --git a/activerecord/lib/active_record/scoping/default.rb b/activerecord/lib/active_record/scoping/default.rb
index ba5cc29ac1..70b2693b28 100644
--- a/activerecord/lib/active_record/scoping/default.rb
+++ b/activerecord/lib/active_record/scoping/default.rb
@@ -107,7 +107,11 @@ module ActiveRecord
if default_scope_override
# The user has defined their own default scope method, so call that
- evaluate_default_scope { default_scope }
+ evaluate_default_scope do
+ if scope = default_scope
+ (base_rel ||= relation).merge(scope)
+ end
+ end
elsif default_scopes.any?
base_rel ||= relation
evaluate_default_scope do
diff --git a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb
index 7043d2f0c8..01562b21e9 100644
--- a/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb
@@ -42,7 +42,7 @@ module ActiveRecord
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
if ignore_tables.any?
- condition = ignore_tables.map { |table| connection.quote_table_name(table) }.join(", ")
+ condition = ignore_tables.map { |table| connection.quote(table) }.join(", ")
args << "SELECT sql FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
else
args << ".schema"
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index 4bf1b5bcd5..f73005b3cb 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -367,19 +367,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
end
- def test_create_by_new_record
- devel = Developer.new(name: "Marcel", salary: 75000)
- devel.projects.build(name: "Make bed")
- proj2 = devel.projects.build(name: "Lie in it")
- assert_equal devel.projects.last, proj2
- assert !proj2.persisted?
- devel.save
- assert devel.persisted?
- assert proj2.persisted?
- assert_equal devel.projects.last, proj2
- assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
- end
-
def test_creation_respects_hash_condition
# in Oracle '' is saved as null therefore need to save ' ' in not null column
post = categories(:general).post_with_conditions.build(body: " ")
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 15c253890b..dc32e995a4 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -907,80 +907,6 @@ class BasicsTest < ActiveRecord::TestCase
end
end
- class NumericData < ActiveRecord::Base
- self.table_name = "numeric_data"
-
- attribute :my_house_population, :integer
- attribute :atoms_in_universe, :integer
- end
-
- def test_big_decimal_conditions
- m = NumericData.new(
- bank_balance: 1586.43,
- big_bank_balance: BigDecimal("1000234000567.95"),
- world_population: 6000000000,
- my_house_population: 3
- )
- assert m.save
- assert_equal 0, NumericData.where("bank_balance > ?", 2000.0).count
- end
-
- def test_numeric_fields
- m = NumericData.new(
- bank_balance: 1586.43,
- big_bank_balance: BigDecimal("1000234000567.95"),
- world_population: 6000000000,
- my_house_population: 3
- )
- assert m.save
-
- m1 = NumericData.find(m.id)
- assert_not_nil m1
-
- # As with migration_test.rb, we should make world_population >= 2**62
- # to cover 64-bit platforms and test it is a Bignum, but the main thing
- # is that it's an Integer.
- assert_kind_of Integer, m1.world_population
- assert_equal 6000000000, m1.world_population
-
- assert_kind_of Integer, m1.my_house_population
- assert_equal 3, m1.my_house_population
-
- assert_kind_of BigDecimal, m1.bank_balance
- assert_equal BigDecimal("1586.43"), m1.bank_balance
-
- assert_kind_of BigDecimal, m1.big_bank_balance
- assert_equal BigDecimal("1000234000567.95"), m1.big_bank_balance
- end
-
- def test_numeric_fields_with_scale
- m = NumericData.new(
- bank_balance: 1586.43122334,
- big_bank_balance: BigDecimal("234000567.952344"),
- world_population: 6000000000,
- my_house_population: 3
- )
- assert m.save
-
- m1 = NumericData.find(m.id)
- assert_not_nil m1
-
- # As with migration_test.rb, we should make world_population >= 2**62
- # to cover 64-bit platforms and test it is a Bignum, but the main thing
- # is that it's an Integer.
- assert_kind_of Integer, m1.world_population
- assert_equal 6000000000, m1.world_population
-
- assert_kind_of Integer, m1.my_house_population
- assert_equal 3, m1.my_house_population
-
- assert_kind_of BigDecimal, m1.bank_balance
- assert_equal BigDecimal("1586.43"), m1.bank_balance
-
- assert_kind_of BigDecimal, m1.big_bank_balance
- assert_equal BigDecimal("234000567.95"), m1.big_bank_balance
- end
-
def test_auto_id
auto = AutoId.new
auto.save
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb
index 93f8ab18c2..21c5c0efee 100644
--- a/activerecord/test/cases/calculations_test.rb
+++ b/activerecord/test/cases/calculations_test.rb
@@ -8,6 +8,7 @@ require "models/organization"
require "models/possession"
require "models/topic"
require "models/reply"
+require "models/numeric_data"
require "models/minivan"
require "models/speedometer"
require "models/ship_part"
@@ -17,14 +18,6 @@ require "models/post"
require "models/comment"
require "models/rating"
-class NumericData < ActiveRecord::Base
- self.table_name = "numeric_data"
-
- attribute :world_population, :integer
- attribute :my_house_population, :integer
- attribute :atoms_in_universe, :integer
-end
-
class CalculationsTest < ActiveRecord::TestCase
fixtures :companies, :accounts, :topics, :speedometers, :minivans, :books
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index 721861975a..f72e0d2ead 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -4,10 +4,7 @@ require "models/pirate" # For timestamps
require "models/parrot"
require "models/person" # For optimistic locking
require "models/aircraft"
-
-class NumericData < ActiveRecord::Base
- self.table_name = "numeric_data"
-end
+require "models/numeric_data"
class DirtyTest < ActiveRecord::TestCase
include InTimeZone
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index b4bbdc6dad..fb5a7bcc31 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -1,6 +1,7 @@
require "cases/helper"
require "models/author"
require "models/company"
+require "models/membership"
require "models/person"
require "models/post"
require "models/project"
@@ -29,7 +30,7 @@ end
class InheritanceTest < ActiveRecord::TestCase
include InheritanceTestHelper
- fixtures :companies, :projects, :subscribers, :accounts, :vegetables
+ fixtures :companies, :projects, :subscribers, :accounts, :vegetables, :memberships
def test_class_with_store_full_sti_class_returns_full_name
with_store_full_sti_class do
@@ -435,6 +436,10 @@ class InheritanceTest < ActiveRecord::TestCase
assert_nothing_raised { Company.of_first_firm }
assert_nothing_raised { Client.of_first_firm }
end
+
+ def test_inheritance_with_default_scope
+ assert_equal 1, SelectedMembership.count(:all)
+ end
end
class InheritanceComputeTypeTest < ActiveRecord::TestCase
diff --git a/activerecord/test/cases/numeric_data_test.rb b/activerecord/test/cases/numeric_data_test.rb
new file mode 100644
index 0000000000..76b97033af
--- /dev/null
+++ b/activerecord/test/cases/numeric_data_test.rb
@@ -0,0 +1,71 @@
+require "cases/helper"
+require "models/numeric_data"
+
+class NumericDataTest < ActiveRecord::TestCase
+ def test_big_decimal_conditions
+ m = NumericData.new(
+ bank_balance: 1586.43,
+ big_bank_balance: BigDecimal("1000234000567.95"),
+ world_population: 6000000000,
+ my_house_population: 3
+ )
+ assert m.save
+ assert_equal 0, NumericData.where("bank_balance > ?", 2000.0).count
+ end
+
+ def test_numeric_fields
+ m = NumericData.new(
+ bank_balance: 1586.43,
+ big_bank_balance: BigDecimal("1000234000567.95"),
+ world_population: 6000000000,
+ my_house_population: 3
+ )
+ assert m.save
+
+ m1 = NumericData.find(m.id)
+ assert_not_nil m1
+
+ # As with migration_test.rb, we should make world_population >= 2**62
+ # to cover 64-bit platforms and test it is a Bignum, but the main thing
+ # is that it's an Integer.
+ assert_kind_of Integer, m1.world_population
+ assert_equal 6000000000, m1.world_population
+
+ assert_kind_of Integer, m1.my_house_population
+ assert_equal 3, m1.my_house_population
+
+ assert_kind_of BigDecimal, m1.bank_balance
+ assert_equal BigDecimal("1586.43"), m1.bank_balance
+
+ assert_kind_of BigDecimal, m1.big_bank_balance
+ assert_equal BigDecimal("1000234000567.95"), m1.big_bank_balance
+ end
+
+ def test_numeric_fields_with_scale
+ m = NumericData.new(
+ bank_balance: 1586.43122334,
+ big_bank_balance: BigDecimal("234000567.952344"),
+ world_population: 6000000000,
+ my_house_population: 3
+ )
+ assert m.save
+
+ m1 = NumericData.find(m.id)
+ assert_not_nil m1
+
+ # As with migration_test.rb, we should make world_population >= 2**62
+ # to cover 64-bit platforms and test it is a Bignum, but the main thing
+ # is that it's an Integer.
+ assert_kind_of Integer, m1.world_population
+ assert_equal 6000000000, m1.world_population
+
+ assert_kind_of Integer, m1.my_house_population
+ assert_equal 3, m1.my_house_population
+
+ assert_kind_of BigDecimal, m1.bank_balance
+ assert_equal BigDecimal("1586.43"), m1.bank_balance
+
+ assert_kind_of BigDecimal, m1.big_bank_balance
+ assert_equal BigDecimal("234000567.95"), m1.big_bank_balance
+ end
+end
diff --git a/activerecord/test/cases/scoping/named_scoping_test.rb b/activerecord/test/cases/scoping/named_scoping_test.rb
index 0c2cffe0d3..483ea7128d 100644
--- a/activerecord/test/cases/scoping/named_scoping_test.rb
+++ b/activerecord/test/cases/scoping/named_scoping_test.rb
@@ -551,6 +551,12 @@ class NamedScopingTest < ActiveRecord::TestCase
assert_equal 1, SpecialComment.where(body: "go crazy").created.count
end
+ def test_model_class_should_respond_to_extending
+ assert_raises OopsError do
+ Comment.unscoped.oops_comments.destroy_all
+ end
+ end
+
def test_model_class_should_respond_to_none
assert !Topic.none?
Topic.delete_all
diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb
index 8cba788598..d227f6fe86 100644
--- a/activerecord/test/models/comment.rb
+++ b/activerecord/test/models/comment.rb
@@ -29,6 +29,8 @@ class Comment < ActiveRecord::Base
default_scope { extending OopsExtension }
+ scope :oops_comments, -> { extending OopsExtension }
+
# Should not be called if extending modules that having the method exists on an association.
def self.greeting
raise
diff --git a/activerecord/test/models/numeric_data.rb b/activerecord/test/models/numeric_data.rb
new file mode 100644
index 0000000000..c6e025a9ce
--- /dev/null
+++ b/activerecord/test/models/numeric_data.rb
@@ -0,0 +1,8 @@
+class NumericData < ActiveRecord::Base
+ self.table_name = "numeric_data"
+ # Decimal columns with 0 scale being automatically treated as integers
+ # is deprecated, and will be removed in a future version of Rails.
+ attribute :world_population, :big_integer
+ attribute :my_house_population, :big_integer
+ attribute :atoms_in_universe, :big_integer
+end
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index fd07187e15..4c3eded38a 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Add `Date#prev_occurring` and `Date#next_occurring` to return specified next/previous occurring day of week.
+
+ *Shota Iguchi*
+
* Add default option to class_attribute. Before:
class_attribute :settings
diff --git a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
index f2ba7fdda5..e2e1d3e359 100644
--- a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb
@@ -320,6 +320,22 @@ module DateAndTime
beginning_of_year..end_of_year
end
+ # Returns specific next occurring day of week
+ def next_occurring(day_of_week)
+ current_day_number = wday != 0 ? wday - 1 : 6
+ from_now = DAYS_INTO_WEEK.fetch(day_of_week) - current_day_number
+ from_now += 7 unless from_now > 0
+ since(from_now.days)
+ end
+
+ # Returns specific previous occurring day of week
+ def prev_occurring(day_of_week)
+ current_day_number = wday != 0 ? wday - 1 : 6
+ ago = current_day_number - DAYS_INTO_WEEK.fetch(day_of_week)
+ ago += 7 unless ago > 0
+ ago(ago.days)
+ end
+
private
def first_hour(date_or_time)
date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time
diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb
index be7c14e9b4..276fa2bfd3 100644
--- a/activesupport/test/core_ext/date_time_ext_test.rb
+++ b/activesupport/test/core_ext/date_time_ext_test.rb
@@ -28,6 +28,28 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
end
end
+ def test_next_occur
+ datetime = DateTime.new(2016, 9, 24, 0, 0) # saturday
+ assert_equal datetime.next_occurring(:monday), datetime.since(2.days)
+ assert_equal datetime.next_occurring(:tuesday), datetime.since(3.days)
+ assert_equal datetime.next_occurring(:wednesday), datetime.since(4.days)
+ assert_equal datetime.next_occurring(:thursday), datetime.since(5.days)
+ assert_equal datetime.next_occurring(:friday), datetime.since(6.days)
+ assert_equal datetime.next_occurring(:saturday), datetime.since(1.week)
+ assert_equal datetime.next_occurring(:sunday), datetime.since(1.day)
+ end
+
+ def test_prev_occur
+ datetime = DateTime.new(2016, 9, 24, 0, 0) # saturday
+ assert_equal datetime.prev_occurring(:monday), datetime.ago(5.days)
+ assert_equal datetime.prev_occurring(:tuesday), datetime.ago(4.days)
+ assert_equal datetime.prev_occurring(:wednesday), datetime.ago(3.days)
+ assert_equal datetime.prev_occurring(:thursday), datetime.ago(2.days)
+ assert_equal datetime.prev_occurring(:friday), datetime.ago(1.day)
+ assert_equal datetime.prev_occurring(:saturday), datetime.ago(1.week)
+ assert_equal datetime.prev_occurring(:sunday), datetime.ago(6.days)
+ end
+
def test_readable_inspect
datetime = DateTime.new(2005, 2, 21, 14, 30, 0)
assert_equal "Mon, 21 Feb 2005 14:30:00 +0000", datetime.readable_inspect
diff --git a/guides/source/asset_pipeline.md b/guides/source/asset_pipeline.md
index 61b7112247..22b6b278d7 100644
--- a/guides/source/asset_pipeline.md
+++ b/guides/source/asset_pipeline.md
@@ -868,7 +868,7 @@ pre-existing JavaScript runtimes, you may want to add one to your Gemfile:
```ruby
group :production do
- gem 'therubyracer'
+ gem 'mini_racer'
end
```
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index 5553f08456..21bd4a3d7a 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -208,7 +208,7 @@ TIP: Compiling CoffeeScript and JavaScript asset compression requires you
have a JavaScript runtime available on your system, in the absence
of a runtime you will see an `execjs` error during asset compilation.
Usually macOS and Windows come with a JavaScript runtime installed.
-Rails adds the `therubyracer` gem to the generated `Gemfile` in a
+Rails adds the `mini_racer` gem to the generated `Gemfile` in a
commented line for new apps and you can uncomment if you need it.
`therubyrhino` is the recommended runtime for JRuby users and is added by
default to the `Gemfile` in apps generated under JRuby. You can investigate
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index e8b104a0b2..8429b6c7b8 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -349,7 +349,7 @@ module Rails
if defined?(JRUBY_VERSION)
GemfileEntry.version "therubyrhino", nil, comment
else
- GemfileEntry.new "therubyracer", nil, comment, { platforms: :ruby }, true
+ GemfileEntry.new "mini_racer", nil, comment, { platforms: :ruby }, true
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index 9c4a77fd1d..d44331a888 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -36,8 +36,8 @@ Rails.application.configure do
config.assets.compile = false
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
- <%- end -%>
+ <%- end -%>
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
@@ -50,8 +50,8 @@ Rails.application.configure do
# config.action_cable.mount_path = nil
# config.action_cable.url = 'wss://example.com/cable'
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
- <%- end -%>
+ <%- end -%>
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
@@ -68,14 +68,15 @@ Rails.application.configure do
# Use a real queuing backend for Active Job (and separate queues per environment)
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "<%= app_name %>_#{Rails.env}"
+
<%- unless options.skip_action_mailer? -%>
config.action_mailer.perform_caching = false
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
- <%- end -%>
+ <%- end -%>
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 31a5efb1b7..8a8c9a35ce 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -468,7 +468,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
if defined?(JRUBY_VERSION)
assert_gem "therubyrhino"
else
- assert_file "Gemfile", /# gem 'therubyracer', platforms: :ruby/
+ assert_file "Gemfile", /# gem 'mini_racer', platforms: :ruby/
end
end