activerecord 4.2.11.3 → 5.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1029 -1349
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -7
- data/examples/performance.rb +2 -2
- data/lib/active_record.rb +7 -3
- data/lib/active_record/aggregations.rb +35 -25
- data/lib/active_record/association_relation.rb +2 -2
- data/lib/active_record/associations.rb +305 -204
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +10 -8
- data/lib/active_record/associations/association_scope.rb +73 -102
- data/lib/active_record/associations/belongs_to_association.rb +20 -32
- data/lib/active_record/associations/builder/association.rb +28 -34
- data/lib/active_record/associations/builder/belongs_to.rb +41 -18
- data/lib/active_record/associations/builder/collection_association.rb +8 -24
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +11 -11
- data/lib/active_record/associations/builder/has_many.rb +4 -4
- data/lib/active_record/associations/builder/has_one.rb +10 -5
- data/lib/active_record/associations/builder/singular_association.rb +2 -9
- data/lib/active_record/associations/collection_association.rb +40 -43
- data/lib/active_record/associations/collection_proxy.rb +55 -29
- data/lib/active_record/associations/foreign_association.rb +1 -1
- data/lib/active_record/associations/has_many_association.rb +20 -71
- data/lib/active_record/associations/has_many_through_association.rb +8 -52
- data/lib/active_record/associations/has_one_association.rb +12 -5
- data/lib/active_record/associations/join_dependency.rb +28 -18
- data/lib/active_record/associations/join_dependency/join_association.rb +13 -12
- data/lib/active_record/associations/preloader.rb +13 -4
- data/lib/active_record/associations/preloader/association.rb +45 -51
- data/lib/active_record/associations/preloader/collection_association.rb +0 -6
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- data/lib/active_record/associations/preloader/has_one.rb +0 -8
- data/lib/active_record/associations/preloader/through_association.rb +5 -4
- data/lib/active_record/associations/singular_association.rb +6 -0
- data/lib/active_record/associations/through_association.rb +11 -3
- data/lib/active_record/attribute.rb +61 -17
- data/lib/active_record/attribute/user_provided_default.rb +23 -0
- data/lib/active_record/attribute_assignment.rb +27 -140
- data/lib/active_record/attribute_decorators.rb +6 -5
- data/lib/active_record/attribute_methods.rb +79 -26
- data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
- data/lib/active_record/attribute_methods/dirty.rb +46 -86
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +26 -42
- data/lib/active_record/attribute_methods/serialization.rb +13 -16
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +42 -9
- data/lib/active_record/attribute_methods/write.rb +13 -24
- data/lib/active_record/attribute_mutation_tracker.rb +70 -0
- data/lib/active_record/attribute_set.rb +30 -3
- data/lib/active_record/attribute_set/builder.rb +6 -4
- data/lib/active_record/attributes.rb +194 -81
- data/lib/active_record/autosave_association.rb +33 -15
- data/lib/active_record/base.rb +30 -18
- data/lib/active_record/callbacks.rb +36 -40
- data/lib/active_record/coders/yaml_column.rb +20 -8
- data/lib/active_record/collection_cache_key.rb +31 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +431 -122
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +40 -22
- data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -8
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +46 -38
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +229 -185
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +52 -13
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +275 -115
- data/lib/active_record/connection_adapters/abstract/transaction.rb +32 -33
- data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -32
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +384 -221
- data/lib/active_record/connection_adapters/column.rb +27 -41
- data/lib/active_record/connection_adapters/connection_specification.rb +2 -21
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +57 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +69 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +59 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +22 -101
- data/lib/active_record/connection_adapters/postgresql/column.rb +6 -10
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +23 -57
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +23 -16
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -11
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +54 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +174 -128
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +184 -112
- data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +15 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +134 -110
- data/lib/active_record/connection_adapters/statement_pool.rb +28 -11
- data/lib/active_record/connection_handling.rb +5 -5
- data/lib/active_record/core.rb +72 -104
- data/lib/active_record/counter_cache.rb +9 -20
- data/lib/active_record/dynamic_matchers.rb +1 -20
- data/lib/active_record/enum.rb +110 -76
- data/lib/active_record/errors.rb +72 -47
- data/lib/active_record/explain_registry.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +19 -4
- data/lib/active_record/fixtures.rb +76 -40
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +27 -40
- data/lib/active_record/integration.rb +4 -4
- data/lib/active_record/legacy_yaml_adapter.rb +18 -2
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +10 -14
- data/lib/active_record/locking/pessimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +40 -22
- data/lib/active_record/migration.rb +304 -133
- data/lib/active_record/migration/command_recorder.rb +59 -18
- data/lib/active_record/migration/compatibility.rb +90 -0
- data/lib/active_record/model_schema.rb +92 -40
- data/lib/active_record/nested_attributes.rb +45 -34
- data/lib/active_record/null_relation.rb +15 -7
- data/lib/active_record/persistence.rb +112 -72
- data/lib/active_record/querying.rb +6 -5
- data/lib/active_record/railtie.rb +20 -13
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +47 -38
- data/lib/active_record/readonly_attributes.rb +1 -1
- data/lib/active_record/reflection.rb +182 -57
- data/lib/active_record/relation.rb +152 -100
- data/lib/active_record/relation/batches.rb +133 -33
- data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
- data/lib/active_record/relation/calculations.rb +80 -101
- data/lib/active_record/relation/delegation.rb +6 -19
- data/lib/active_record/relation/finder_methods.rb +58 -46
- data/lib/active_record/relation/from_clause.rb +32 -0
- data/lib/active_record/relation/merger.rb +13 -42
- data/lib/active_record/relation/predicate_builder.rb +99 -105
- data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +78 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
- data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +17 -0
- data/lib/active_record/relation/query_attribute.rb +19 -0
- data/lib/active_record/relation/query_methods.rb +274 -238
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +3 -6
- data/lib/active_record/relation/where_clause.rb +173 -0
- data/lib/active_record/relation/where_clause_factory.rb +37 -0
- data/lib/active_record/result.rb +4 -3
- data/lib/active_record/runtime_registry.rb +1 -1
- data/lib/active_record/sanitization.rb +94 -65
- data/lib/active_record/schema.rb +23 -22
- data/lib/active_record/schema_dumper.rb +33 -22
- data/lib/active_record/schema_migration.rb +10 -4
- data/lib/active_record/scoping.rb +17 -6
- data/lib/active_record/scoping/default.rb +19 -6
- data/lib/active_record/scoping/named.rb +39 -28
- data/lib/active_record/secure_token.rb +38 -0
- data/lib/active_record/serialization.rb +2 -4
- data/lib/active_record/statement_cache.rb +15 -13
- data/lib/active_record/store.rb +8 -3
- data/lib/active_record/suppressor.rb +54 -0
- data/lib/active_record/table_metadata.rb +64 -0
- data/lib/active_record/tasks/database_tasks.rb +30 -40
- data/lib/active_record/tasks/mysql_database_tasks.rb +7 -15
- data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
- data/lib/active_record/timestamp.rb +16 -9
- data/lib/active_record/touch_later.rb +58 -0
- data/lib/active_record/transactions.rb +138 -56
- data/lib/active_record/type.rb +66 -17
- data/lib/active_record/type/adapter_specific_registry.rb +130 -0
- data/lib/active_record/type/date.rb +2 -45
- data/lib/active_record/type/date_time.rb +2 -49
- data/lib/active_record/type/internal/abstract_json.rb +33 -0
- data/lib/active_record/type/internal/timezone.rb +15 -0
- data/lib/active_record/type/serialized.rb +9 -14
- data/lib/active_record/type/time.rb +3 -21
- data/lib/active_record/type/type_map.rb +4 -4
- data/lib/active_record/type_caster.rb +7 -0
- data/lib/active_record/type_caster/connection.rb +29 -0
- data/lib/active_record/type_caster/map.rb +19 -0
- data/lib/active_record/validations.rb +33 -32
- data/lib/active_record/validations/absence.rb +24 -0
- data/lib/active_record/validations/associated.rb +10 -3
- data/lib/active_record/validations/length.rb +36 -0
- data/lib/active_record/validations/presence.rb +12 -12
- data/lib/active_record/validations/uniqueness.rb +24 -21
- data/lib/rails/generators/active_record/migration.rb +7 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
- data/lib/rails/generators/active_record/migration/templates/migration.rb +4 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +21 -15
- data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
- metadata +50 -35
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -31
- data/lib/active_record/type/decimal.rb +0 -64
- data/lib/active_record/type/decimal_without_scale.rb +0 -11
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -59
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -40
- data/lib/active_record/type/text.rb +0 -11
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/unsigned_integer.rb +0 -15
- data/lib/active_record/type/value.rb +0 -110
@@ -19,10 +19,10 @@ module ActiveRecord
|
|
19
19
|
if Numeric === value || value !~ /[^0-9]/
|
20
20
|
!value.to_i.zero?
|
21
21
|
else
|
22
|
-
return false if
|
22
|
+
return false if ActiveModel::Type::Boolean::FALSE_VALUES.include?(value)
|
23
23
|
!value.blank?
|
24
24
|
end
|
25
|
-
elsif
|
25
|
+
elsif value.respond_to?(:zero?)
|
26
26
|
!value.zero?
|
27
27
|
else
|
28
28
|
!value.blank?
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/module/method_transplanting'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
module AttributeMethods
|
5
3
|
module Read
|
@@ -36,68 +34,54 @@ module ActiveRecord
|
|
36
34
|
extend ActiveSupport::Concern
|
37
35
|
|
38
36
|
module ClassMethods
|
39
|
-
[:cache_attributes, :cached_attributes, :cache_attribute?].each do |method_name|
|
40
|
-
define_method method_name do |*|
|
41
|
-
cached_attributes_deprecation_warning(method_name)
|
42
|
-
true
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
37
|
protected
|
47
38
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
if Module.methods_transplantable?
|
53
|
-
def define_method_attribute(name)
|
54
|
-
method = ReaderMethodCache[name]
|
55
|
-
generated_attribute_methods.module_eval { define_method name, method }
|
56
|
-
end
|
57
|
-
else
|
58
|
-
def define_method_attribute(name)
|
59
|
-
safe_name = name.unpack('h*').first
|
60
|
-
temp_method = "__temp__#{safe_name}"
|
39
|
+
def define_method_attribute(name)
|
40
|
+
safe_name = name.unpack('h*'.freeze).first
|
41
|
+
temp_method = "__temp__#{safe_name}"
|
61
42
|
|
62
|
-
|
43
|
+
ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
|
63
44
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
69
|
-
STR
|
70
|
-
|
71
|
-
generated_attribute_methods.module_eval do
|
72
|
-
alias_method name, temp_method
|
73
|
-
undef_method temp_method
|
45
|
+
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
46
|
+
def #{temp_method}
|
47
|
+
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
|
48
|
+
_read_attribute(name) { |n| missing_attribute(n, caller) }
|
74
49
|
end
|
50
|
+
STR
|
51
|
+
|
52
|
+
generated_attribute_methods.module_eval do
|
53
|
+
alias_method name, temp_method
|
54
|
+
undef_method temp_method
|
75
55
|
end
|
76
56
|
end
|
77
57
|
end
|
78
58
|
|
79
|
-
ID = 'id'.freeze
|
80
|
-
|
81
59
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after
|
82
60
|
# it has been typecast (for example, "2004-12-12" in a date column is cast
|
83
61
|
# to a date object, like Date.new(2004, 12, 12)).
|
84
62
|
def read_attribute(attr_name, &block)
|
85
63
|
name = attr_name.to_s
|
86
|
-
name = self.class.primary_key if name ==
|
64
|
+
name = self.class.primary_key if name == 'id'.freeze
|
87
65
|
_read_attribute(name, &block)
|
88
66
|
end
|
89
67
|
|
90
68
|
# This method exists to avoid the expensive primary_key check internally, without
|
91
69
|
# breaking compatibility with the read_attribute API
|
92
|
-
|
93
|
-
|
70
|
+
if defined?(JRUBY_VERSION)
|
71
|
+
# This form is significantly faster on JRuby, and this is one of our biggest hotspots.
|
72
|
+
# https://github.com/jruby/jruby/pull/2562
|
73
|
+
def _read_attribute(attr_name, &block) # :nodoc
|
74
|
+
@attributes.fetch_value(attr_name.to_s, &block)
|
75
|
+
end
|
76
|
+
else
|
77
|
+
def _read_attribute(attr_name) # :nodoc:
|
78
|
+
@attributes.fetch_value(attr_name.to_s) { |n| yield n if block_given? }
|
79
|
+
end
|
94
80
|
end
|
95
81
|
|
96
|
-
|
82
|
+
alias :attribute :_read_attribute
|
83
|
+
private :attribute
|
97
84
|
|
98
|
-
def attribute(attribute_name)
|
99
|
-
_read_attribute(attribute_name)
|
100
|
-
end
|
101
85
|
end
|
102
86
|
end
|
103
87
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/string/filters'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
module AttributeMethods
|
5
3
|
module Serialization
|
@@ -11,7 +9,19 @@ module ActiveRecord
|
|
11
9
|
# attribute using this method and it will be handled automatically. The
|
12
10
|
# serialization is done through YAML. If +class_name+ is specified, the
|
13
11
|
# serialized object must be of that class on assignment and retrieval.
|
14
|
-
# Otherwise
|
12
|
+
# Otherwise SerializationTypeMismatch will be raised.
|
13
|
+
#
|
14
|
+
# Empty objects as <tt>{}</tt>, in the case of +Hash+, or <tt>[]</tt>, in the case of
|
15
|
+
# +Array+, will always be persisted as null.
|
16
|
+
#
|
17
|
+
# Keep in mind that database adapters handle certain serialization tasks
|
18
|
+
# for you. For instance: +json+ and +jsonb+ types in PostgreSQL will be
|
19
|
+
# converted between JSON object/array syntax and Ruby +Hash+ or +Array+
|
20
|
+
# objects transparently. There is no need to use #serialize in this
|
21
|
+
# case.
|
22
|
+
#
|
23
|
+
# For more complex cases, such as conversion to or from your application
|
24
|
+
# domain objects, consider using the ActiveRecord::Attributes API.
|
15
25
|
#
|
16
26
|
# ==== Parameters
|
17
27
|
#
|
@@ -51,19 +61,6 @@ module ActiveRecord
|
|
51
61
|
Type::Serialized.new(type, coder)
|
52
62
|
end
|
53
63
|
end
|
54
|
-
|
55
|
-
def serialized_attributes
|
56
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
57
|
-
`serialized_attributes` is deprecated without replacement, and will
|
58
|
-
be removed in Rails 5.0.
|
59
|
-
MSG
|
60
|
-
|
61
|
-
@serialized_attributes ||= Hash[
|
62
|
-
columns.select { |t| t.cast_type.is_a?(Type::Serialized) }.map { |c|
|
63
|
-
[c.name, c.cast_type.coder]
|
64
|
-
}
|
65
|
-
]
|
66
|
-
end
|
67
64
|
end
|
68
65
|
end
|
69
66
|
end
|
@@ -1,25 +1,29 @@
|
|
1
|
+
require 'active_support/core_ext/string/strip'
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
module TimeZoneConversion
|
4
6
|
class TimeZoneConverter < DelegateClass(Type::Value) # :nodoc:
|
5
|
-
|
6
|
-
|
7
|
-
def type_cast_from_database(value)
|
7
|
+
def deserialize(value)
|
8
8
|
convert_time_to_time_zone(super)
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
11
|
+
def cast(value)
|
12
12
|
if value.is_a?(Array)
|
13
|
-
value.map { |v|
|
13
|
+
value.map { |v| cast(v) }
|
14
|
+
elsif value.is_a?(Hash)
|
15
|
+
set_time_zone_without_conversion(super)
|
14
16
|
elsif value.respond_to?(:in_time_zone)
|
15
17
|
begin
|
16
|
-
value
|
18
|
+
super(user_input_in_time_zone(value)) || super
|
17
19
|
rescue ArgumentError
|
18
20
|
nil
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
25
|
+
private
|
26
|
+
|
23
27
|
def convert_time_to_time_zone(value)
|
24
28
|
if value.is_a?(Array)
|
25
29
|
value.map { |v| convert_time_to_time_zone(v) }
|
@@ -29,6 +33,10 @@ module ActiveRecord
|
|
29
33
|
value
|
30
34
|
end
|
31
35
|
end
|
36
|
+
|
37
|
+
def set_time_zone_without_conversion(value)
|
38
|
+
::Time.zone.local_to_utc(value).in_time_zone
|
39
|
+
end
|
32
40
|
end
|
33
41
|
|
34
42
|
extend ActiveSupport::Concern
|
@@ -39,6 +47,9 @@ module ActiveRecord
|
|
39
47
|
|
40
48
|
class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false
|
41
49
|
self.skip_time_zone_conversion_for_attributes = []
|
50
|
+
|
51
|
+
class_attribute :time_zone_aware_types, instance_writer: false
|
52
|
+
self.time_zone_aware_types = [:datetime, :not_explicitly_configured]
|
42
53
|
end
|
43
54
|
|
44
55
|
module ClassMethods
|
@@ -59,9 +70,31 @@ module ActiveRecord
|
|
59
70
|
end
|
60
71
|
|
61
72
|
def create_time_zone_conversion_attribute?(name, cast_type)
|
62
|
-
time_zone_aware_attributes &&
|
63
|
-
!self.skip_time_zone_conversion_for_attributes.include?(name.to_sym)
|
64
|
-
|
73
|
+
enabled_for_column = time_zone_aware_attributes &&
|
74
|
+
!self.skip_time_zone_conversion_for_attributes.include?(name.to_sym)
|
75
|
+
result = enabled_for_column &&
|
76
|
+
time_zone_aware_types.include?(cast_type.type)
|
77
|
+
|
78
|
+
if enabled_for_column &&
|
79
|
+
!result &&
|
80
|
+
cast_type.type == :time &&
|
81
|
+
time_zone_aware_types.include?(:not_explicitly_configured)
|
82
|
+
ActiveSupport::Deprecation.warn(<<-MESSAGE.strip_heredoc)
|
83
|
+
Time columns will become time zone aware in Rails 5.1. This
|
84
|
+
still causes `String`s to be parsed as if they were in `Time.zone`,
|
85
|
+
and `Time`s to be converted to `Time.zone`.
|
86
|
+
|
87
|
+
To keep the old behavior, you must add the following to your initializer:
|
88
|
+
|
89
|
+
config.active_record.time_zone_aware_types = [:datetime]
|
90
|
+
|
91
|
+
To silence this deprecation warning, add the following:
|
92
|
+
|
93
|
+
config.active_record.time_zone_aware_types << :time
|
94
|
+
MESSAGE
|
95
|
+
end
|
96
|
+
|
97
|
+
result
|
65
98
|
end
|
66
99
|
end
|
67
100
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/module/method_transplanting'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
module AttributeMethods
|
5
3
|
module Write
|
@@ -25,38 +23,29 @@ module ActiveRecord
|
|
25
23
|
module ClassMethods
|
26
24
|
protected
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
generated_attribute_methods.module_eval {
|
32
|
-
define_method "#{name}=", method
|
33
|
-
}
|
34
|
-
end
|
35
|
-
else
|
36
|
-
def define_method_attribute=(name)
|
37
|
-
safe_name = name.unpack('h*').first
|
38
|
-
ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
|
26
|
+
def define_method_attribute=(name)
|
27
|
+
safe_name = name.unpack('h*'.freeze).first
|
28
|
+
ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
|
39
29
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
30
|
+
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
31
|
+
def __temp__#{safe_name}=(value)
|
32
|
+
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
|
33
|
+
write_attribute(name, value)
|
34
|
+
end
|
35
|
+
alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
|
36
|
+
undef_method :__temp__#{safe_name}=
|
37
|
+
STR
|
49
38
|
end
|
50
39
|
end
|
51
40
|
|
52
41
|
# Updates the attribute identified by <tt>attr_name</tt> with the
|
53
|
-
# specified +value+. Empty strings for
|
42
|
+
# specified +value+. Empty strings for fixnum and float columns are
|
54
43
|
# turned into +nil+.
|
55
44
|
def write_attribute(attr_name, value)
|
56
45
|
write_attribute_with_type_cast(attr_name, value, true)
|
57
46
|
end
|
58
47
|
|
59
|
-
def raw_write_attribute(attr_name, value)
|
48
|
+
def raw_write_attribute(attr_name, value) # :nodoc:
|
60
49
|
write_attribute_with_type_cast(attr_name, value, false)
|
61
50
|
end
|
62
51
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
class AttributeMutationTracker # :nodoc:
|
3
|
+
def initialize(attributes)
|
4
|
+
@attributes = attributes
|
5
|
+
end
|
6
|
+
|
7
|
+
def changed_values
|
8
|
+
attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
|
9
|
+
if changed?(attr_name)
|
10
|
+
result[attr_name] = attributes[attr_name].original_value
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def changes
|
16
|
+
attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
|
17
|
+
if changed?(attr_name)
|
18
|
+
result[attr_name] = [attributes[attr_name].original_value, attributes.fetch_value(attr_name)]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def changed?(attr_name)
|
24
|
+
attr_name = attr_name.to_s
|
25
|
+
attributes[attr_name].changed?
|
26
|
+
end
|
27
|
+
|
28
|
+
def changed_in_place?(attr_name)
|
29
|
+
attributes[attr_name].changed_in_place?
|
30
|
+
end
|
31
|
+
|
32
|
+
def forget_change(attr_name)
|
33
|
+
attr_name = attr_name.to_s
|
34
|
+
attributes[attr_name] = attributes[attr_name].forgetting_assignment
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
attr_reader :attributes
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def attr_names
|
44
|
+
attributes.keys
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class NullMutationTracker # :nodoc:
|
49
|
+
include Singleton
|
50
|
+
|
51
|
+
def changed_values
|
52
|
+
{}
|
53
|
+
end
|
54
|
+
|
55
|
+
def changes
|
56
|
+
{}
|
57
|
+
end
|
58
|
+
|
59
|
+
def changed?(*)
|
60
|
+
false
|
61
|
+
end
|
62
|
+
|
63
|
+
def changed_in_place?(*)
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
def forget_change(*)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -10,6 +10,10 @@ module ActiveRecord
|
|
10
10
|
attributes[name] || Attribute.null(name)
|
11
11
|
end
|
12
12
|
|
13
|
+
def []=(name, value)
|
14
|
+
attributes[name] = value
|
15
|
+
end
|
16
|
+
|
13
17
|
def values_before_type_cast
|
14
18
|
attributes.transform_values(&:value_before_type_cast)
|
15
19
|
end
|
@@ -24,11 +28,19 @@ module ActiveRecord
|
|
24
28
|
end
|
25
29
|
|
26
30
|
def keys
|
27
|
-
attributes.
|
31
|
+
attributes.each_key.select { |name| self[name].initialized? }
|
28
32
|
end
|
29
33
|
|
30
|
-
|
31
|
-
|
34
|
+
if defined?(JRUBY_VERSION)
|
35
|
+
# This form is significantly faster on JRuby, and this is one of our biggest hotspots.
|
36
|
+
# https://github.com/jruby/jruby/pull/2562
|
37
|
+
def fetch_value(name, &block)
|
38
|
+
self[name].value(&block)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
def fetch_value(name)
|
42
|
+
self[name].value { |n| yield n if block_given? }
|
43
|
+
end
|
32
44
|
end
|
33
45
|
|
34
46
|
def write_from_database(name, value)
|
@@ -48,6 +60,12 @@ module ActiveRecord
|
|
48
60
|
super
|
49
61
|
end
|
50
62
|
|
63
|
+
def deep_dup
|
64
|
+
dup.tap do |copy|
|
65
|
+
copy.instance_variable_set(:@attributes, attributes.deep_dup)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
51
69
|
def initialize_dup(_)
|
52
70
|
@attributes = attributes.dup
|
53
71
|
super
|
@@ -64,6 +82,15 @@ module ActiveRecord
|
|
64
82
|
end
|
65
83
|
end
|
66
84
|
|
85
|
+
def accessed
|
86
|
+
attributes.select { |_, attr| attr.has_been_read? }.keys
|
87
|
+
end
|
88
|
+
|
89
|
+
def map(&block)
|
90
|
+
new_attributes = attributes.transform_values(&block)
|
91
|
+
AttributeSet.new(new_attributes)
|
92
|
+
end
|
93
|
+
|
67
94
|
def ==(other)
|
68
95
|
attributes == other.attributes
|
69
96
|
end
|
@@ -22,7 +22,7 @@ module ActiveRecord
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class LazyAttributeHash # :nodoc:
|
25
|
-
delegate :transform_values, to: :materialize
|
25
|
+
delegate :transform_values, :each_key, to: :materialize
|
26
26
|
|
27
27
|
def initialize(types, values, additional_types)
|
28
28
|
@types = types
|
@@ -47,12 +47,14 @@ module ActiveRecord
|
|
47
47
|
delegate_hash[key] = value
|
48
48
|
end
|
49
49
|
|
50
|
-
def
|
51
|
-
|
50
|
+
def deep_dup
|
51
|
+
dup.tap do |copy|
|
52
|
+
copy.instance_variable_set(:@delegate_hash, delegate_hash.transform_values(&:dup))
|
53
|
+
end
|
52
54
|
end
|
53
55
|
|
54
56
|
def initialize_dup(_)
|
55
|
-
@delegate_hash = delegate_hash
|
57
|
+
@delegate_hash = Hash[delegate_hash]
|
56
58
|
super
|
57
59
|
end
|
58
60
|
|