aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RELEASING_RAILS.rdoc1
-rw-r--r--actionview/CHANGELOG.md10
-rw-r--r--actionview/lib/action_view/helpers/tags/file_field.rb4
-rw-r--r--actionview/test/template/form_helper_test.rb4
-rw-r--r--activerecord/CHANGELOG.md26
-rw-r--r--activerecord/lib/active_record/associations/builder/association.rb60
-rw-r--r--activerecord/lib/active_record/associations/builder/belongs_to.rb6
-rw-r--r--activerecord/lib/active_record/associations/builder/collection_association.rb24
-rw-r--r--activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb10
-rw-r--r--activerecord/lib/active_record/associations/builder/has_many.rb4
-rw-r--r--activerecord/lib/active_record/associations/builder/has_one.rb6
-rw-r--r--activerecord/lib/active_record/associations/builder/singular_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/collection_association.rb6
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb40
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/column.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb15
-rw-r--r--activerecord/lib/active_record/dynamic_matchers.rb21
-rw-r--r--activerecord/lib/active_record/null_relation.rb4
-rw-r--r--activerecord/lib/active_record/reflection.rb2
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb37
-rw-r--r--activerecord/lib/active_record/schema_dumper.rb11
-rw-r--r--activerecord/test/cases/adapters/mysql/datetime_test.rb87
-rw-r--r--activerecord/test/cases/adapters/mysql2/datetime_test.rb87
-rw-r--r--activerecord/test/cases/associations/extension_test.rb3
-rw-r--r--activerecord/test/cases/associations/inverse_associations_test.rb12
-rw-r--r--activerecord/test/cases/primary_keys_test.rb19
-rw-r--r--activerecord/test/cases/relations_test.rb2
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb7
-rw-r--r--activerecord/test/schema/schema.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/thread.rb86
-rw-r--r--activesupport/test/core_ext/thread_test.rb75
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb2
-rw-r--r--guides/source/active_record_querying.md2
35 files changed, 387 insertions, 306 deletions
diff --git a/RELEASING_RAILS.rdoc b/RELEASING_RAILS.rdoc
index 4aab3b35ba..ee5e6a91c1 100644
--- a/RELEASING_RAILS.rdoc
+++ b/RELEASING_RAILS.rdoc
@@ -33,7 +33,6 @@ after some refactoring or bug fix, so it is important to check if the following
are working with the versions that will be released:
* https://github.com/rails/protected_attributes
-* https://github.com/rails/activerecord-deprecated_finders
Do not release red plugins tests.
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index 4fa468dd91..6abfd8b364 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,12 +1,12 @@
-* Add an explicit error message, in `ActionView::PartialRenderer` for partial
- `rendering`, when the value of option `as` has invalid characters.
-
- *Angelo Capilleri*
-
* Add a `hidden_field` on the `file_field` to avoid raise a error when the only
input on the form is the `file_field`.
*Mauro George*
+* Add an explicit error message, in `ActionView::PartialRenderer` for partial
+ `rendering`, when the value of option `as` has invalid characters.
+
+ *Angelo Capilleri*
+
Please check [4-2-stable](https://github.com/rails/rails/blob/4-2-stable/actionview/CHANGELOG.md) for previous changes.
diff --git a/actionview/lib/action_view/helpers/tags/file_field.rb b/actionview/lib/action_view/helpers/tags/file_field.rb
index 02585fa0ae..e6a1d9c62d 100644
--- a/actionview/lib/action_view/helpers/tags/file_field.rb
+++ b/actionview/lib/action_view/helpers/tags/file_field.rb
@@ -5,13 +5,15 @@ module ActionView
def render
options = @options.stringify_keys
+
if options.fetch("include_hidden", true)
add_default_name_and_id(options)
options[:type] = "file"
- tag("input", :name => options["name"], :type => "hidden", :value => "") + tag("input", options)
+ tag("input", name: options["name"], type: "hidden", value: "") + tag("input", options)
else
options.delete("include_hidden")
@options = options
+
super
end
end
diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb
index 0b3d78ea9b..fff1e1e572 100644
--- a/actionview/test/template/form_helper_test.rb
+++ b/actionview/test/template/form_helper_test.rb
@@ -479,12 +479,12 @@ class FormHelperTest < ActionView::TestCase
def test_file_field_does_not_generate_a_hidden_field_if_included_hidden_option_is_false
expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
- assert_dom_equal expected, file_field("user", "avatar", :include_hidden => false)
+ assert_dom_equal expected, file_field("user", "avatar", include_hidden: false)
end
def test_file_field_does_not_generate_a_hidden_field_if_included_hidden_option_is_false_with_key_as_string
expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
- assert_dom_equal expected, file_field("user", "avatar", 'include_hidden' => false)
+ assert_dom_equal expected, file_field("user", "avatar", "include_hidden" => false)
end
def test_file_field_has_no_size
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index f473e84575..64e3890b76 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,29 @@
+* Improve a dump of the primary key support. If it is not a default primary key,
+ correctly dump the type and options.
+
+ Fixes #14169, #16599.
+
+ *Ryuta Kamizono*
+
+* Format the datetime string according to the precision of the datetime field.
+
+ Incompatible to rounding behavior between MySQL 5.6 and earlier.
+
+ In 5.5, when you insert `2014-08-17 12:30:00.999999` the fractional part
+ is ignored. In 5.6, it's rounded to `2014-08-17 12:30:01`:
+
+ http://bugs.mysql.com/bug.php?id=68760
+
+ *Ryuta Kamizono*
+
+* Allow precision option for MySQL datetimes.
+
+ *Ryuta Kamizono*
+
+* Fixed automatic inverse_of for models nested in module.
+
+ *Andrew McCloud*
+
* Change `ActiveRecord::Relation#update` behavior so that it can
be called without passing ids of the records to be updated.
diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb
index 947d61ee7b..88406740d8 100644
--- a/activerecord/lib/active_record/associations/builder/association.rb
+++ b/activerecord/lib/active_record/associations/builder/association.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/module/attribute_accessors'
-
# This is the parent Association class which defines the variables
# used by all associations.
#
@@ -15,15 +13,10 @@ module ActiveRecord::Associations::Builder
class Association #:nodoc:
class << self
attr_accessor :extensions
- # TODO: This class accessor is needed to make activerecord-deprecated_finders work.
- # We can move it to a constant in 5.0.
- attr_accessor :valid_options
end
self.extensions = []
- self.valid_options = [:class_name, :class, :foreign_key, :validate]
-
- attr_reader :name, :scope, :options
+ VALID_OPTIONS = [:class_name, :class, :foreign_key, :validate] # :nodoc:
def self.build(model, name, scope, options, &block)
if model.dangerous_attribute_method?(name)
@@ -32,57 +25,60 @@ module ActiveRecord::Associations::Builder
"Please choose a different association name."
end
- builder = create_builder model, name, scope, options, &block
- reflection = builder.build(model)
+ extension = define_extensions model, name, &block
+ reflection = create_reflection model, name, scope, options, extension
define_accessors model, reflection
define_callbacks model, reflection
define_validations model, reflection
- builder.define_extensions model
reflection
end
- def self.create_builder(model, name, scope, options, &block)
+ def self.create_reflection(model, name, scope, options, extension = nil)
raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol)
- new(model, name, scope, options, &block)
- end
-
- def initialize(model, name, scope, options)
- # TODO: Move this to create_builder as soon we drop support to activerecord-deprecated_finders.
if scope.is_a?(Hash)
options = scope
scope = nil
end
- # TODO: Remove this model argument as soon we drop support to activerecord-deprecated_finders.
- @name = name
- @scope = scope
- @options = options
+ validate_options(options)
- validate_options
+ scope = build_scope(scope, extension)
+
+ ActiveRecord::Reflection.create(macro, name, scope, options, model)
+ end
+
+ def self.build_scope(scope, extension)
+ new_scope = scope
if scope && scope.arity == 0
- @scope = proc { instance_exec(&scope) }
+ new_scope = proc { instance_exec(&scope) }
+ end
+
+ if extension
+ new_scope = wrap_scope new_scope, extension
end
+
+ new_scope
end
- def build(model)
- ActiveRecord::Reflection.create(macro, name, scope, options, model)
+ def self.wrap_scope(scope, extension)
+ scope
end
- def macro
+ def self.macro
raise NotImplementedError
end
- def valid_options
- Association.valid_options + Association.extensions.flat_map(&:valid_options)
+ def self.valid_options(options)
+ VALID_OPTIONS + Association.extensions.flat_map(&:valid_options)
end
- def validate_options
- options.assert_valid_keys(valid_options)
+ def self.validate_options(options)
+ options.assert_valid_keys(valid_options(options))
end
- def define_extensions(model)
+ def self.define_extensions(model, name)
end
def self.define_callbacks(model, reflection)
@@ -133,8 +129,6 @@ module ActiveRecord::Associations::Builder
raise NotImplementedError
end
- private
-
def self.check_dependent_options(dependent)
unless valid_dependent_options.include? dependent
raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{dependent}"
diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb
index 954ea3878a..d0ad57f9c6 100644
--- a/activerecord/lib/active_record/associations/builder/belongs_to.rb
+++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb
@@ -1,10 +1,10 @@
module ActiveRecord::Associations::Builder
class BelongsTo < SingularAssociation #:nodoc:
- def macro
+ def self.macro
:belongs_to
end
- def valid_options
+ def self.valid_options(options)
super + [:foreign_type, :polymorphic, :touch, :counter_cache]
end
@@ -23,8 +23,6 @@ module ActiveRecord::Associations::Builder
add_counter_cache_methods mixin
end
- private
-
def self.add_counter_cache_methods(mixin)
return if mixin.method_defined? :belongs_to_counter_cache_after_update
diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb
index bc15a49996..2ff67f904d 100644
--- a/activerecord/lib/active_record/associations/builder/collection_association.rb
+++ b/activerecord/lib/active_record/associations/builder/collection_association.rb
@@ -7,22 +7,11 @@ module ActiveRecord::Associations::Builder
CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove]
- def valid_options
+ def self.valid_options(options)
super + [:table_name, :before_add,
:after_add, :before_remove, :after_remove, :extend]
end
- attr_reader :block_extension
-
- def initialize(model, name, scope, options)
- super
- @mod = nil
- if block_given?
- @mod = Module.new(&Proc.new)
- @scope = wrap_scope @scope, @mod
- end
- end
-
def self.define_callbacks(model, reflection)
super
name = reflection.name
@@ -32,10 +21,11 @@ module ActiveRecord::Associations::Builder
}
end
- def define_extensions(model)
- if @mod
+ def self.define_extensions(model, name)
+ if block_given?
extension_module_name = "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension"
- model.parent.const_set(extension_module_name, @mod)
+ extension = Module.new(&Proc.new)
+ model.parent.const_set(extension_module_name, extension)
end
end
@@ -78,9 +68,7 @@ module ActiveRecord::Associations::Builder
CODE
end
- private
-
- def wrap_scope(scope, mod)
+ def self.wrap_scope(scope, mod)
if scope
proc { |owner| instance_exec(owner, &scope).extending(mod) }
else
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 092b4ebd2f..93dc4ae118 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
@@ -87,11 +87,11 @@ module ActiveRecord::Associations::Builder
middle_name = [lhs_model.name.downcase.pluralize,
association_name].join('_').gsub(/::/, '_').to_sym
middle_options = middle_options join_model
- hm_builder = HasMany.create_builder(lhs_model,
- middle_name,
- nil,
- middle_options)
- hm_builder.build lhs_model
+
+ HasMany.create_reflection(lhs_model,
+ middle_name,
+ nil,
+ middle_options)
end
private
diff --git a/activerecord/lib/active_record/associations/builder/has_many.rb b/activerecord/lib/active_record/associations/builder/has_many.rb
index 1b87f92170..1c1b47bd56 100644
--- a/activerecord/lib/active_record/associations/builder/has_many.rb
+++ b/activerecord/lib/active_record/associations/builder/has_many.rb
@@ -1,10 +1,10 @@
module ActiveRecord::Associations::Builder
class HasMany < CollectionAssociation #:nodoc:
- def macro
+ def self.macro
:has_many
end
- def valid_options
+ def self.valid_options(options)
super + [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of, :counter_cache, :join_table, :foreign_type]
end
diff --git a/activerecord/lib/active_record/associations/builder/has_one.rb b/activerecord/lib/active_record/associations/builder/has_one.rb
index 1387717396..64e9e6b334 100644
--- a/activerecord/lib/active_record/associations/builder/has_one.rb
+++ b/activerecord/lib/active_record/associations/builder/has_one.rb
@@ -1,10 +1,10 @@
module ActiveRecord::Associations::Builder
class HasOne < SingularAssociation #:nodoc:
- def macro
+ def self.macro
:has_one
end
- def valid_options
+ def self.valid_options(options)
valid = super + [:as, :foreign_type]
valid += [:through, :source, :source_type] if options[:through]
valid
@@ -14,8 +14,6 @@ module ActiveRecord::Associations::Builder
[:destroy, :delete, :nullify, :restrict_with_error, :restrict_with_exception]
end
- private
-
def self.add_destroy_callbacks(model, reflection)
super unless reflection.options[:through]
end
diff --git a/activerecord/lib/active_record/associations/builder/singular_association.rb b/activerecord/lib/active_record/associations/builder/singular_association.rb
index 6e6dd7204c..1369212837 100644
--- a/activerecord/lib/active_record/associations/builder/singular_association.rb
+++ b/activerecord/lib/active_record/associations/builder/singular_association.rb
@@ -2,7 +2,7 @@
module ActiveRecord::Associations::Builder
class SingularAssociation < Association #:nodoc:
- def valid_options
+ def self.valid_options(options)
super + [:dependent, :primary_key, :inverse_of, :required]
end
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb
index 16b1228b8a..f2c96e9a2a 100644
--- a/activerecord/lib/active_record/associations/collection_association.rb
+++ b/activerecord/lib/active_record/associations/collection_association.rb
@@ -218,11 +218,7 @@ module ActiveRecord
# Count all records using SQL. Construct options and pass them with
# scope to the target class's +count+.
- def count(column_name = nil, count_options = {})
- # TODO: Remove count_options argument as soon we remove support to
- # activerecord-deprecated_finders.
- column_name, count_options = nil, column_name if column_name.is_a?(Hash)
-
+ def count(column_name = nil)
relation = scope
if association_scope.distinct_value
# This is needed because 'SELECT count(DISTINCT *)..' is not valid SQL.
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index dc42b19a83..c22dc6e11e 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -688,10 +688,8 @@ module ActiveRecord
# # #<Pet id: 2, name: "Spook", person_id: 1>,
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# # ]
- def count(column_name = nil, options = {})
- # TODO: Remove options argument as soon we remove support to
- # activerecord-deprecated_finders.
- @association.count(column_name, options)
+ def count(column_name = nil)
+ @association.count(column_name)
end
# Returns the size of the collection. If the collection hasn't been loaded,
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
index 0834105079..42ea599a74 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
@@ -12,6 +12,12 @@ module ActiveRecord
spec
end
+ def column_spec_for_primary_key(column)
+ return if column.type == :integer
+ spec = { id: column.type.inspect }
+ spec.merge!(prepare_column_options(column).delete_if { |key, _| [:name, :type].include?(key) })
+ end
+
# This can be overridden on a Adapter level basis to support other
# extended datatypes (Example: Adding an array option in the
# PostgreSQLAdapter)
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index d083e413a5..a8fee56259 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -65,6 +65,18 @@ module ActiveRecord
SchemaCreation.new self
end
+ def column_spec_for_primary_key(column)
+ spec = {}
+ if column.extra == 'auto_increment'
+ return unless column.limit == 8
+ spec[:id] = ':bigint'
+ else
+ spec[:id] = column.type.inspect
+ spec.merge!(prepare_column_options(column).delete_if { |key, _| [:name, :type, :null].include?(key) })
+ end
+ spec
+ end
+
class Column < ConnectionAdapters::Column # :nodoc:
attr_reader :collation, :strict, :extra
@@ -591,6 +603,13 @@ module ActiveRecord
when 0x1000000..0xffffffff; 'longtext'
else raise(ActiveRecordError, "No text type has character length #{limit}")
end
+ when 'datetime'
+ return super unless precision
+
+ case precision
+ when 0..6; "datetime(#{precision})"
+ else raise(ActiveRecordError, "No datetime type has precision of #{precision}. The allowed range of precision is from 0 to 6.")
+ end
else
super
end
@@ -679,6 +698,11 @@ module ActiveRecord
m.alias_type %r(year)i, 'integer'
m.alias_type %r(bit)i, 'binary'
+ m.register_type(%r(datetime)i) do |sql_type|
+ precision = extract_precision(sql_type)
+ MysqlDateTime.new(precision: precision)
+ end
+
m.register_type(%r(enum)i) do |sql_type|
limit = sql_type[/^enum\((.+)\)/i, 1]
.split(',').map{|enum| enum.strip.length - 2}.max
@@ -872,6 +896,22 @@ module ActiveRecord
TableDefinition.new(native_database_types, name, temporary, options, as)
end
+ class MysqlDateTime < Type::DateTime # :nodoc:
+ def type_cast_for_database(value)
+ if value.acts_like?(:time) && value.respond_to?(:usec)
+ result = super.to_s(:db)
+ case precision
+ when 1..6
+ "#{result}.#{sprintf("%0#{precision}d", value.usec / 10 ** (6 - precision))}"
+ else
+ result
+ end
+ else
+ super
+ end
+ end
+ end
+
class MysqlString < Type::String # :nodoc:
def type_cast_for_database(value)
case value
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
index 37e5c3859c..1458fbf496 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/column.rb
@@ -15,6 +15,10 @@ module ActiveRecord
@default_function = default_function
end
+
+ def serial?
+ default_function && default_function =~ /\Anextval\(.*\)\z/
+ end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 02cafc8079..6053e33a20 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -125,6 +125,21 @@ module ActiveRecord
PostgreSQL::SchemaCreation.new self
end
+ def column_spec_for_primary_key(column)
+ spec = {}
+ if column.serial?
+ return unless column.sql_type == 'bigint'
+ spec[:id] = ':bigserial'
+ elsif column.type == :uuid
+ spec[:id] = ':uuid'
+ spec[:default] = column.default_function.inspect
+ else
+ spec[:id] = column.type.inspect
+ spec.merge!(prepare_column_options(column).delete_if { |key, _| [:name, :type, :null].include?(key) })
+ end
+ spec
+ end
+
# Adds +:array+ option to the default set provided by the
# AbstractAdapter
def prepare_column_options(column) # :nodoc:
diff --git a/activerecord/lib/active_record/dynamic_matchers.rb b/activerecord/lib/active_record/dynamic_matchers.rb
index e94b74063e..b6dd6814db 100644
--- a/activerecord/lib/active_record/dynamic_matchers.rb
+++ b/activerecord/lib/active_record/dynamic_matchers.rb
@@ -1,10 +1,5 @@
module ActiveRecord
module DynamicMatchers #:nodoc:
- # This code in this file seems to have a lot of indirection, but the indirection
- # is there to provide extension points for the activerecord-deprecated_finders
- # gem. When we stop supporting activerecord-deprecated_finders (from Rails 5),
- # then we can remove the indirection.
-
def respond_to?(name, include_private = false)
if self == Base
super
@@ -72,26 +67,14 @@ module ActiveRecord
CODE
end
- def body
- raise NotImplementedError
- end
- end
+ private
- module Finder
- # Extended in activerecord-deprecated_finders
def body
- result
- end
-
- # Extended in activerecord-deprecated_finders
- def result
"#{finder}(#{attributes_hash})"
end
# The parameters in the signature may have reserved Ruby words, in order
# to prevent errors, we start each param name with `_`.
- #
- # Extended in activerecord-deprecated_finders
def signature
attribute_names.map { |name| "_#{name}" }.join(', ')
end
@@ -109,7 +92,6 @@ module ActiveRecord
class FindBy < Method
Method.matchers << self
- include Finder
def self.prefix
"find_by"
@@ -122,7 +104,6 @@ module ActiveRecord
class FindByBang < Method
Method.matchers << self
- include Finder
def self.prefix
"find_by"
diff --git a/activerecord/lib/active_record/null_relation.rb b/activerecord/lib/active_record/null_relation.rb
index 807c301596..b406da14dc 100644
--- a/activerecord/lib/active_record/null_relation.rb
+++ b/activerecord/lib/active_record/null_relation.rb
@@ -62,9 +62,7 @@ module ActiveRecord
calculate :maximum, nil
end
- def calculate(operation, _column_name, _options = {})
- # TODO: Remove _options argument as soon we remove support to
- # activerecord-deprecated_finders.
+ def calculate(operation, _column_name)
if [:count, :sum, :size].include? operation
group_values.any? ? Hash.new : 0
elsif [:average, :minimum, :maximum].include?(operation) && group_values.any?
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 9849e03036..dd746a4e10 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -499,7 +499,7 @@ module ActiveRecord
# returns either nil or the inverse association name that it finds.
def automatic_inverse_of
if can_find_inverse_of_automatically?(self)
- inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name).to_sym
+ inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym
begin
reflection = klass._reflect_on_association(inverse_name)
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index 71673324eb..1d4cb1a83b 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -35,21 +35,16 @@ module ActiveRecord
#
# Note: not all valid +select+ expressions are valid +count+ expressions. The specifics differ
# between databases. In invalid cases, an error from the database is thrown.
- def count(column_name = nil, options = {})
- # TODO: Remove options argument as soon we remove support to
- # activerecord-deprecated_finders.
- column_name, options = nil, column_name if column_name.is_a?(Hash)
- calculate(:count, column_name, options)
+ def count(column_name = nil)
+ calculate(:count, column_name)
end
# Calculates the average value on a given column. Returns +nil+ if there's
# no row. See +calculate+ for examples with options.
#
# Person.average(:age) # => 35.8
- def average(column_name, options = {})
- # TODO: Remove options argument as soon we remove support to
- # activerecord-deprecated_finders.
- calculate(:average, column_name, options)
+ def average(column_name)
+ calculate(:average, column_name)
end
# Calculates the minimum value on a given column. The value is returned
@@ -57,10 +52,8 @@ module ActiveRecord
# +calculate+ for examples with options.
#
# Person.minimum(:age) # => 7
- def minimum(column_name, options = {})
- # TODO: Remove options argument as soon we remove support to
- # activerecord-deprecated_finders.
- calculate(:minimum, column_name, options)
+ def minimum(column_name)
+ calculate(:minimum, column_name)
end
# Calculates the maximum value on a given column. The value is returned
@@ -68,10 +61,8 @@ module ActiveRecord
# +calculate+ for examples with options.
#
# Person.maximum(:age) # => 93
- def maximum(column_name, options = {})
- # TODO: Remove options argument as soon we remove support to
- # activerecord-deprecated_finders.
- calculate(:maximum, column_name, options)
+ def maximum(column_name)
+ calculate(:maximum, column_name)
end
# Calculates the sum of values on a given column. The value is returned
@@ -114,17 +105,15 @@ module ActiveRecord
# Person.group(:last_name).having("min(age) > 17").minimum(:age)
#
# Person.sum("2 * age")
- def calculate(operation, column_name, options = {})
- # TODO: Remove options argument as soon we remove support to
- # activerecord-deprecated_finders.
+ def calculate(operation, column_name)
if column_name.is_a?(Symbol) && attribute_alias?(column_name)
column_name = attribute_alias(column_name)
end
if has_include?(column_name)
- construct_relation_for_association_calculations.calculate(operation, column_name, options)
+ construct_relation_for_association_calculations.calculate(operation, column_name)
else
- perform_calculation(operation, column_name, options)
+ perform_calculation(operation, column_name)
end
end
@@ -196,9 +185,7 @@ module ActiveRecord
eager_loading? || (includes_values.present? && ((column_name && column_name != :all) || references_eager_loaded_tables?))
end
- def perform_calculation(operation, column_name, options = {})
- # TODO: Remove options argument as soon we remove support to
- # activerecord-deprecated_finders.
+ def perform_calculation(operation, column_name)
operation = operation.to_s.downcase
# If #count is used with #distinct / #uniq it is considered distinct. (eg. relation.distinct.count)
diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb
index 2a570e1323..da95920571 100644
--- a/activerecord/lib/active_record/schema_dumper.rb
+++ b/activerecord/lib/active_record/schema_dumper.rb
@@ -117,11 +117,12 @@ HEADER
if pkcol
if pk != 'id'
tbl.print %Q(, primary_key: "#{pk}")
- elsif pkcol.sql_type == 'bigint'
- tbl.print ", id: :bigserial"
- elsif pkcol.sql_type == 'uuid'
- tbl.print ", id: :uuid"
- tbl.print %Q(, default: #{pkcol.default_function.inspect})
+ end
+ pkcolspec = @connection.column_spec_for_primary_key(pkcol)
+ if pkcolspec
+ pkcolspec.each do |key, value|
+ tbl.print ", #{key}: #{value}"
+ end
end
else
tbl.print ", id: false"
diff --git a/activerecord/test/cases/adapters/mysql/datetime_test.rb b/activerecord/test/cases/adapters/mysql/datetime_test.rb
new file mode 100644
index 0000000000..ae00f4e131
--- /dev/null
+++ b/activerecord/test/cases/adapters/mysql/datetime_test.rb
@@ -0,0 +1,87 @@
+require 'cases/helper'
+
+if mysql_56?
+ class DateTimeTest < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
+
+ class Foo < ActiveRecord::Base; end
+
+ def test_default_datetime_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true)
+ ActiveRecord::Base.connection.add_column :foos, :created_at, :datetime
+ ActiveRecord::Base.connection.add_column :foos, :updated_at, :datetime
+ assert_nil activerecord_column_option('foos', 'created_at', 'precision')
+ end
+
+ def test_datetime_data_type_with_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true)
+ ActiveRecord::Base.connection.add_column :foos, :created_at, :datetime, precision: 1
+ ActiveRecord::Base.connection.add_column :foos, :updated_at, :datetime, precision: 5
+ assert_equal 1, activerecord_column_option('foos', 'created_at', 'precision')
+ assert_equal 5, activerecord_column_option('foos', 'updated_at', 'precision')
+ end
+
+ def test_timestamps_helper_with_custom_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.timestamps null: true, precision: 4
+ end
+ assert_equal 4, activerecord_column_option('foos', 'created_at', 'precision')
+ assert_equal 4, activerecord_column_option('foos', 'updated_at', 'precision')
+ end
+
+ def test_passing_precision_to_datetime_does_not_set_limit
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.timestamps null: true, precision: 4
+ end
+ assert_nil activerecord_column_option('foos', 'created_at', 'limit')
+ assert_nil activerecord_column_option('foos', 'updated_at', 'limit')
+ end
+
+ def test_invalid_datetime_precision_raises_error
+ assert_raises ActiveRecord::ActiveRecordError do
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.timestamps null: true, precision: 7
+ end
+ end
+ end
+
+ def test_mysql_agrees_with_activerecord_about_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.timestamps null: true, precision: 4
+ end
+ assert_equal 4, mysql_datetime_precision('foos', 'created_at')
+ assert_equal 4, mysql_datetime_precision('foos', 'updated_at')
+ end
+
+ def test_formatting_datetime_according_to_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.datetime :created_at, precision: 0
+ t.datetime :updated_at, precision: 4
+ end
+ date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
+ Foo.create!(created_at: date, updated_at: date)
+ assert foo = Foo.find_by(created_at: date)
+ assert_equal date.to_s, foo.created_at.to_s
+ assert_equal date.to_s, foo.updated_at.to_s
+ assert_equal 000000, foo.created_at.usec
+ assert_equal 999900, foo.updated_at.usec
+ end
+
+ private
+
+ def mysql_datetime_precision(table_name, column_name)
+ results = ActiveRecord::Base.connection.exec_query("SELECT column_name, datetime_precision FROM information_schema.columns WHERE table_name = '#{table_name}'")
+ result = results.find do |result_hash|
+ result_hash["column_name"] == column_name
+ end
+ result && result["datetime_precision"]
+ end
+
+ def activerecord_column_option(tablename, column_name, option)
+ result = ActiveRecord::Base.connection.columns(tablename).find do |column|
+ column.name == column_name
+ end
+ result && result.send(option)
+ end
+ end
+end
diff --git a/activerecord/test/cases/adapters/mysql2/datetime_test.rb b/activerecord/test/cases/adapters/mysql2/datetime_test.rb
new file mode 100644
index 0000000000..ae00f4e131
--- /dev/null
+++ b/activerecord/test/cases/adapters/mysql2/datetime_test.rb
@@ -0,0 +1,87 @@
+require 'cases/helper'
+
+if mysql_56?
+ class DateTimeTest < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
+
+ class Foo < ActiveRecord::Base; end
+
+ def test_default_datetime_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true)
+ ActiveRecord::Base.connection.add_column :foos, :created_at, :datetime
+ ActiveRecord::Base.connection.add_column :foos, :updated_at, :datetime
+ assert_nil activerecord_column_option('foos', 'created_at', 'precision')
+ end
+
+ def test_datetime_data_type_with_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true)
+ ActiveRecord::Base.connection.add_column :foos, :created_at, :datetime, precision: 1
+ ActiveRecord::Base.connection.add_column :foos, :updated_at, :datetime, precision: 5
+ assert_equal 1, activerecord_column_option('foos', 'created_at', 'precision')
+ assert_equal 5, activerecord_column_option('foos', 'updated_at', 'precision')
+ end
+
+ def test_timestamps_helper_with_custom_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.timestamps null: true, precision: 4
+ end
+ assert_equal 4, activerecord_column_option('foos', 'created_at', 'precision')
+ assert_equal 4, activerecord_column_option('foos', 'updated_at', 'precision')
+ end
+
+ def test_passing_precision_to_datetime_does_not_set_limit
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.timestamps null: true, precision: 4
+ end
+ assert_nil activerecord_column_option('foos', 'created_at', 'limit')
+ assert_nil activerecord_column_option('foos', 'updated_at', 'limit')
+ end
+
+ def test_invalid_datetime_precision_raises_error
+ assert_raises ActiveRecord::ActiveRecordError do
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.timestamps null: true, precision: 7
+ end
+ end
+ end
+
+ def test_mysql_agrees_with_activerecord_about_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.timestamps null: true, precision: 4
+ end
+ assert_equal 4, mysql_datetime_precision('foos', 'created_at')
+ assert_equal 4, mysql_datetime_precision('foos', 'updated_at')
+ end
+
+ def test_formatting_datetime_according_to_precision
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
+ t.datetime :created_at, precision: 0
+ t.datetime :updated_at, precision: 4
+ end
+ date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
+ Foo.create!(created_at: date, updated_at: date)
+ assert foo = Foo.find_by(created_at: date)
+ assert_equal date.to_s, foo.created_at.to_s
+ assert_equal date.to_s, foo.updated_at.to_s
+ assert_equal 000000, foo.created_at.usec
+ assert_equal 999900, foo.updated_at.usec
+ end
+
+ private
+
+ def mysql_datetime_precision(table_name, column_name)
+ results = ActiveRecord::Base.connection.exec_query("SELECT column_name, datetime_precision FROM information_schema.columns WHERE table_name = '#{table_name}'")
+ result = results.find do |result_hash|
+ result_hash["column_name"] == column_name
+ end
+ result && result["datetime_precision"]
+ end
+
+ def activerecord_column_option(tablename, column_name, option)
+ result = ActiveRecord::Base.connection.columns(tablename).find do |column|
+ column.name == column_name
+ end
+ result && result.send(option)
+ end
+ end
+end
diff --git a/activerecord/test/cases/associations/extension_test.rb b/activerecord/test/cases/associations/extension_test.rb
index 9d373cd73b..b161cde335 100644
--- a/activerecord/test/cases/associations/extension_test.rb
+++ b/activerecord/test/cases/associations/extension_test.rb
@@ -76,7 +76,6 @@ class AssociationsExtensionsTest < ActiveRecord::TestCase
private
def extend!(model)
- builder = ActiveRecord::Associations::Builder::HasMany.new(model, :association_name, nil, {}) { }
- builder.define_extensions(model)
+ ActiveRecord::Associations::Builder::HasMany.define_extensions(model, :association_name) { }
end
end
diff --git a/activerecord/test/cases/associations/inverse_associations_test.rb b/activerecord/test/cases/associations/inverse_associations_test.rb
index 60df4e14dd..423b8238b1 100644
--- a/activerecord/test/cases/associations/inverse_associations_test.rb
+++ b/activerecord/test/cases/associations/inverse_associations_test.rb
@@ -10,6 +10,9 @@ require 'models/comment'
require 'models/car'
require 'models/bulb'
require 'models/mixed_case_monkey'
+require 'models/admin'
+require 'models/admin/account'
+require 'models/admin/user'
class AutomaticInverseFindingTests < ActiveRecord::TestCase
fixtures :ratings, :comments, :cars
@@ -27,6 +30,15 @@ class AutomaticInverseFindingTests < ActiveRecord::TestCase
assert_equal monkey_reflection, man_reflection.inverse_of, "The man reflection's inverse should be the monkey reflection"
end
+ def test_has_many_and_belongs_to_should_find_inverse_automatically_for_model_in_module
+ account_reflection = Admin::Account.reflect_on_association(:users)
+ user_reflection = Admin::User.reflect_on_association(:account)
+
+ assert_respond_to account_reflection, :has_inverse?
+ assert account_reflection.has_inverse?, "The Admin::Account reflection should have an inverse"
+ assert_equal user_reflection, account_reflection.inverse_of, "The Admin::Account reflection's inverse should be the Admin::User reflection"
+ end
+
def test_has_one_and_belongs_to_should_find_inverse_automatically
car_reflection = Car.reflect_on_association(:bulb)
bulb_reflection = Bulb.reflect_on_association(:car)
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 2dfc53f132..751eccc015 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -1,4 +1,5 @@
require "cases/helper"
+require 'support/schema_dumping_helper'
require 'models/topic'
require 'models/reply'
require 'models/subscriber'
@@ -196,6 +197,8 @@ class PrimaryKeyWithNoConnectionTest < ActiveRecord::TestCase
end
class PrimaryKeyAnyTypeTest < ActiveRecord::TestCase
+ include SchemaDumpingHelper
+
self.use_transactional_fixtures = false
class Barcode < ActiveRecord::Base
@@ -217,6 +220,11 @@ class PrimaryKeyAnyTypeTest < ActiveRecord::TestCase
assert_equal :string, column_type.type
assert_equal 42, column_type.limit
end
+
+ test "schema dump primary key includes type and options" do
+ schema = dump_table_schema "barcodes"
+ assert_match %r{create_table "barcodes", primary_key: "code", id: :string, limit: 42}, schema
+ end
end
if current_adapter?(:MysqlAdapter, :Mysql2Adapter)
@@ -235,6 +243,8 @@ end
if current_adapter?(:PostgreSQLAdapter, :MysqlAdapter, :Mysql2Adapter)
class PrimaryKeyBigSerialTest < ActiveRecord::TestCase
+ include SchemaDumpingHelper
+
self.use_transactional_fixtures = false
class Widget < ActiveRecord::Base
@@ -263,5 +273,14 @@ if current_adapter?(:PostgreSQLAdapter, :MysqlAdapter, :Mysql2Adapter)
widget = Widget.create!
assert_not_nil widget.id
end
+
+ test "schema dump primary key with bigserial" do
+ schema = dump_table_schema "widgets"
+ if current_adapter?(:PostgreSQLAdapter)
+ assert_match %r{create_table "widgets", id: :bigserial}, schema
+ else
+ assert_match %r{create_table "widgets", id: :bigint}, schema
+ end
+ end
end
end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index 0210ae6487..fb9258c038 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -358,7 +358,7 @@ class RelationTest < ActiveRecord::TestCase
def test_null_relation_calculations_methods
assert_no_queries(ignore_none: false) do
assert_equal 0, Developer.none.count
- assert_equal 0, Developer.none.calculate(:count, nil, {})
+ assert_equal 0, Developer.none.calculate(:count, nil)
assert_equal nil, Developer.none.calculate(:average, 'salary')
end
end
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index a094136766..57b7346503 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -232,6 +232,13 @@ class SchemaDumperTest < ActiveRecord::TestCase
end
end
+ if mysql_56?
+ def test_schema_dump_includes_datetime_precision
+ output = standard_dump
+ assert_match %r{t.datetime\s+"written_on",\s+precision: 6$}, output
+ end
+ end
+
def test_schema_dump_includes_decimal_options
output = dump_all_table_schema([/^[^n]/])
assert_match %r{precision: 3,[[:space:]]+scale: 2,[[:space:]]+default: 2.78}, output
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index a9c2b1d112..5907d6ef97 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -726,7 +726,7 @@ ActiveRecord::Schema.define do
t.string :author_name
t.string :author_email_address
if mysql_56?
- t.datetime :written_on, limit: 6
+ t.datetime :written_on, precision: 6
else
t.datetime :written_on
end
diff --git a/activesupport/lib/active_support/core_ext/thread.rb b/activesupport/lib/active_support/core_ext/thread.rb
deleted file mode 100644
index 9637178f53..0000000000
--- a/activesupport/lib/active_support/core_ext/thread.rb
+++ /dev/null
@@ -1,86 +0,0 @@
-class Thread
- LOCK = Mutex.new # :nodoc:
-
- # Returns the value of a thread local variable that has been set. Note that
- # these are different than fiber local values.
- #
- # Thread local values are carried along with threads, and do not respect
- # fibers. For example:
- #
- # Thread.new {
- # Thread.current.thread_variable_set("foo", "bar") # set a thread local
- # Thread.current["foo"] = "bar" # set a fiber local
- #
- # Fiber.new {
- # Fiber.yield [
- # Thread.current.thread_variable_get("foo"), # get the thread local
- # Thread.current["foo"], # get the fiber local
- # ]
- # }.resume
- # }.join.value # => ['bar', nil]
- #
- # The value <tt>"bar"</tt> is returned for the thread local, where +nil+ is returned
- # for the fiber local. The fiber is executed in the same thread, so the
- # thread local values are available.
- def thread_variable_get(key)
- _locals[key.to_sym]
- end
-
- # Sets a thread local with +key+ to +value+. Note that these are local to
- # threads, and not to fibers. Please see Thread#thread_variable_get for
- # more information.
- def thread_variable_set(key, value)
- _locals[key.to_sym] = value
- end
-
- # Returns an array of the names of the thread-local variables (as Symbols).
- #
- # thr = Thread.new do
- # Thread.current.thread_variable_set(:cat, 'meow')
- # Thread.current.thread_variable_set("dog", 'woof')
- # end
- # thr.join # => #<Thread:0x401b3f10 dead>
- # thr.thread_variables # => [:dog, :cat]
- #
- # Note that these are not fiber local variables. Please see Thread#thread_variable_get
- # for more details.
- def thread_variables
- _locals.keys
- end
-
- # Returns <tt>true</tt> if the given string (or symbol) exists as a
- # thread-local variable.
- #
- # me = Thread.current
- # me.thread_variable_set(:oliver, "a")
- # me.thread_variable?(:oliver) # => true
- # me.thread_variable?(:stanley) # => false
- #
- # Note that these are not fiber local variables. Please see Thread#thread_variable_get
- # for more details.
- def thread_variable?(key)
- _locals.has_key?(key.to_sym)
- end
-
- # Freezes the thread so that thread local variables cannot be set via
- # Thread#thread_variable_set, nor can fiber local variables be set.
- #
- # me = Thread.current
- # me.freeze
- # me.thread_variable_set(:oliver, "a") # => RuntimeError: can't modify frozen thread locals
- # me[:oliver] = "a" # => RuntimeError: can't modify frozen thread locals
- def freeze
- _locals.freeze
- super
- end
-
- private
-
- def _locals
- if defined?(@_locals)
- @_locals
- else
- LOCK.synchronize { @_locals ||= {} }
- end
- end
-end unless Thread.instance_methods.include?(:thread_variable_set)
diff --git a/activesupport/test/core_ext/thread_test.rb b/activesupport/test/core_ext/thread_test.rb
deleted file mode 100644
index 6a7c6e0604..0000000000
--- a/activesupport/test/core_ext/thread_test.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require 'abstract_unit'
-require 'active_support/core_ext/thread'
-
-class ThreadExt < ActiveSupport::TestCase
- def test_main_thread_variable_in_enumerator
- assert_equal Thread.main, Thread.current
-
- Thread.current.thread_variable_set :foo, "bar"
-
- thread, value = Fiber.new {
- Fiber.yield [Thread.current, Thread.current.thread_variable_get(:foo)]
- }.resume
-
- assert_equal Thread.current, thread
- assert_equal Thread.current.thread_variable_get(:foo), value
- end
-
- def test_thread_variable_in_enumerator
- Thread.new {
- Thread.current.thread_variable_set :foo, "bar"
-
- thread, value = Fiber.new {
- Fiber.yield [Thread.current, Thread.current.thread_variable_get(:foo)]
- }.resume
-
- assert_equal Thread.current, thread
- assert_equal Thread.current.thread_variable_get(:foo), value
- }.join
- end
-
- def test_thread_variables
- assert_equal [], Thread.new { Thread.current.thread_variables }.join.value
-
- t = Thread.new {
- Thread.current.thread_variable_set(:foo, "bar")
- Thread.current.thread_variables
- }
- assert_equal [:foo], t.join.value
- end
-
- def test_thread_variable?
- assert_not Thread.new { Thread.current.thread_variable?("foo") }.join.value
- t = Thread.new {
- Thread.current.thread_variable_set("foo", "bar")
- }.join
-
- assert t.thread_variable?("foo")
- assert t.thread_variable?(:foo)
- assert_not t.thread_variable?(:bar)
- end
-
- def test_thread_variable_strings_and_symbols_are_the_same_key
- t = Thread.new {}.join
- t.thread_variable_set("foo", "bar")
- assert_equal "bar", t.thread_variable_get(:foo)
- end
-
- def test_thread_variable_frozen
- t = Thread.new { }.join
- t.freeze
- assert_raises(RuntimeError) do
- t.thread_variable_set(:foo, "bar")
- end
- end
-
- def test_thread_variable_frozen_after_set
- t = Thread.new { }.join
- t.thread_variable_set :foo, "bar"
- t.freeze
- assert_raises(RuntimeError) do
- t.thread_variable_set(:baz, "qux")
- end
- end
-
-end
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index ad4062e5fe..92c233d567 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -812,6 +812,8 @@ class TimeWithZoneTest < ActiveSupport::TestCase
end
def test_no_method_error_has_proper_context
+ rubinius_skip "Error message inconsistency"
+
e = assert_raises(NoMethodError) {
@twz.this_method_does_not_exist
}
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index 476456eef7..e0a9add2be 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -1389,8 +1389,6 @@ NOTE: Remember that, if `find_by` returns more than one registry, it will take j
Find or Build a New Object
--------------------------
-NOTE: Some dynamic finders were deprecated in Rails 4.0 and removed in Rails 4.1. The best practice is to use Active Record scopes instead. You can find the deprecation gem at https://github.com/rails/activerecord-deprecated_finders
-
It's common that you need to find a record or create it if it doesn't exist. You can do that with the `find_or_create_by` and `find_or_create_by!` methods.
### `find_or_create_by`