activerecord 5.0.7.2 → 5.1.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.

Files changed (216) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +389 -2252
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +28 -28
  6. data/examples/simple.rb +3 -3
  7. data/lib/active_record.rb +20 -20
  8. data/lib/active_record/aggregations.rb +244 -244
  9. data/lib/active_record/association_relation.rb +5 -5
  10. data/lib/active_record/associations.rb +1579 -1569
  11. data/lib/active_record/associations/alias_tracker.rb +1 -1
  12. data/lib/active_record/associations/association.rb +23 -15
  13. data/lib/active_record/associations/association_scope.rb +83 -81
  14. data/lib/active_record/associations/belongs_to_association.rb +0 -1
  15. data/lib/active_record/associations/builder/belongs_to.rb +16 -14
  16. data/lib/active_record/associations/builder/collection_association.rb +1 -2
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
  18. data/lib/active_record/associations/collection_association.rb +74 -241
  19. data/lib/active_record/associations/collection_proxy.rb +144 -70
  20. data/lib/active_record/associations/has_many_association.rb +15 -19
  21. data/lib/active_record/associations/has_many_through_association.rb +12 -5
  22. data/lib/active_record/associations/has_one_association.rb +22 -28
  23. data/lib/active_record/associations/has_one_through_association.rb +5 -1
  24. data/lib/active_record/associations/join_dependency.rb +117 -115
  25. data/lib/active_record/associations/join_dependency/join_association.rb +16 -13
  26. data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
  27. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  28. data/lib/active_record/associations/preloader.rb +94 -94
  29. data/lib/active_record/associations/preloader/association.rb +87 -64
  30. data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
  31. data/lib/active_record/associations/preloader/collection_association.rb +6 -6
  32. data/lib/active_record/associations/preloader/has_many.rb +0 -2
  33. data/lib/active_record/associations/preloader/singular_association.rb +6 -8
  34. data/lib/active_record/associations/preloader/through_association.rb +34 -41
  35. data/lib/active_record/associations/singular_association.rb +8 -25
  36. data/lib/active_record/associations/through_association.rb +3 -6
  37. data/lib/active_record/attribute.rb +98 -71
  38. data/lib/active_record/attribute/user_provided_default.rb +4 -2
  39. data/lib/active_record/attribute_assignment.rb +61 -61
  40. data/lib/active_record/attribute_decorators.rb +35 -13
  41. data/lib/active_record/attribute_methods.rb +56 -65
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
  43. data/lib/active_record/attribute_methods/dirty.rb +216 -34
  44. data/lib/active_record/attribute_methods/primary_key.rb +78 -73
  45. data/lib/active_record/attribute_methods/read.rb +39 -35
  46. data/lib/active_record/attribute_methods/serialization.rb +7 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
  48. data/lib/active_record/attribute_methods/write.rb +36 -30
  49. data/lib/active_record/attribute_mutation_tracker.rb +53 -10
  50. data/lib/active_record/attribute_set.rb +9 -6
  51. data/lib/active_record/attribute_set/builder.rb +41 -49
  52. data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
  53. data/lib/active_record/attributes.rb +21 -21
  54. data/lib/active_record/autosave_association.rb +13 -13
  55. data/lib/active_record/base.rb +24 -22
  56. data/lib/active_record/callbacks.rb +52 -14
  57. data/lib/active_record/coders/yaml_column.rb +9 -11
  58. data/lib/active_record/collection_cache_key.rb +6 -17
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +320 -278
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +22 -34
  62. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -27
  63. data/lib/active_record/connection_adapters/abstract/quoting.rb +44 -57
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +9 -19
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +78 -79
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +99 -93
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +1 -5
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +156 -128
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +424 -382
  71. data/lib/active_record/connection_adapters/column.rb +27 -5
  72. data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
  73. data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -43
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +49 -31
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +5 -6
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +24 -26
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -28
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -35
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +9 -9
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
  92. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
  93. data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
  94. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  95. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
  97. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +28 -30
  98. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
  100. data/lib/active_record/connection_adapters/postgresql/quoting.rb +38 -36
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +161 -170
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +4 -4
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -7
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +179 -152
  108. data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
  110. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -20
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
  113. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
  114. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
  115. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +187 -130
  116. data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
  117. data/lib/active_record/connection_handling.rb +14 -26
  118. data/lib/active_record/core.rb +110 -93
  119. data/lib/active_record/counter_cache.rb +62 -13
  120. data/lib/active_record/define_callbacks.rb +20 -0
  121. data/lib/active_record/dynamic_matchers.rb +80 -79
  122. data/lib/active_record/enum.rb +8 -6
  123. data/lib/active_record/errors.rb +58 -15
  124. data/lib/active_record/explain.rb +1 -2
  125. data/lib/active_record/explain_registry.rb +1 -1
  126. data/lib/active_record/explain_subscriber.rb +7 -4
  127. data/lib/active_record/fixture_set/file.rb +11 -8
  128. data/lib/active_record/fixtures.rb +66 -53
  129. data/lib/active_record/gem_version.rb +3 -3
  130. data/lib/active_record/inheritance.rb +93 -79
  131. data/lib/active_record/integration.rb +7 -7
  132. data/lib/active_record/internal_metadata.rb +3 -16
  133. data/lib/active_record/legacy_yaml_adapter.rb +1 -1
  134. data/lib/active_record/locking/optimistic.rb +64 -56
  135. data/lib/active_record/locking/pessimistic.rb +10 -1
  136. data/lib/active_record/log_subscriber.rb +29 -29
  137. data/lib/active_record/migration.rb +155 -172
  138. data/lib/active_record/migration/command_recorder.rb +94 -94
  139. data/lib/active_record/migration/compatibility.rb +76 -37
  140. data/lib/active_record/migration/join_table.rb +6 -6
  141. data/lib/active_record/model_schema.rb +85 -119
  142. data/lib/active_record/nested_attributes.rb +200 -199
  143. data/lib/active_record/null_relation.rb +10 -33
  144. data/lib/active_record/persistence.rb +45 -38
  145. data/lib/active_record/query_cache.rb +4 -8
  146. data/lib/active_record/querying.rb +2 -3
  147. data/lib/active_record/railtie.rb +16 -17
  148. data/lib/active_record/railties/controller_runtime.rb +6 -2
  149. data/lib/active_record/railties/databases.rake +125 -140
  150. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  151. data/lib/active_record/readonly_attributes.rb +2 -2
  152. data/lib/active_record/reflection.rb +79 -96
  153. data/lib/active_record/relation.rb +72 -115
  154. data/lib/active_record/relation/batches.rb +87 -58
  155. data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
  156. data/lib/active_record/relation/calculations.rb +154 -160
  157. data/lib/active_record/relation/delegation.rb +30 -29
  158. data/lib/active_record/relation/finder_methods.rb +195 -226
  159. data/lib/active_record/relation/merger.rb +58 -62
  160. data/lib/active_record/relation/predicate_builder.rb +92 -89
  161. data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
  162. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
  163. data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
  164. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
  165. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
  166. data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
  167. data/lib/active_record/relation/query_attribute.rb +1 -1
  168. data/lib/active_record/relation/query_methods.rb +247 -295
  169. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  170. data/lib/active_record/relation/spawn_methods.rb +4 -5
  171. data/lib/active_record/relation/where_clause.rb +79 -65
  172. data/lib/active_record/relation/where_clause_factory.rb +47 -8
  173. data/lib/active_record/result.rb +29 -31
  174. data/lib/active_record/runtime_registry.rb +3 -3
  175. data/lib/active_record/sanitization.rb +182 -197
  176. data/lib/active_record/schema.rb +3 -3
  177. data/lib/active_record/schema_dumper.rb +14 -37
  178. data/lib/active_record/schema_migration.rb +3 -3
  179. data/lib/active_record/scoping.rb +9 -10
  180. data/lib/active_record/scoping/default.rb +87 -91
  181. data/lib/active_record/scoping/named.rb +16 -28
  182. data/lib/active_record/secure_token.rb +2 -2
  183. data/lib/active_record/statement_cache.rb +13 -15
  184. data/lib/active_record/store.rb +31 -32
  185. data/lib/active_record/suppressor.rb +2 -1
  186. data/lib/active_record/table_metadata.rb +9 -5
  187. data/lib/active_record/tasks/database_tasks.rb +72 -65
  188. data/lib/active_record/tasks/mysql_database_tasks.rb +75 -72
  189. data/lib/active_record/tasks/postgresql_database_tasks.rb +53 -48
  190. data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
  191. data/lib/active_record/timestamp.rb +39 -25
  192. data/lib/active_record/touch_later.rb +1 -2
  193. data/lib/active_record/transactions.rb +98 -110
  194. data/lib/active_record/type.rb +17 -13
  195. data/lib/active_record/type/adapter_specific_registry.rb +46 -42
  196. data/lib/active_record/type/decimal_without_scale.rb +9 -0
  197. data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
  198. data/lib/active_record/type/serialized.rb +8 -8
  199. data/lib/active_record/type/text.rb +9 -0
  200. data/lib/active_record/type/time.rb +0 -1
  201. data/lib/active_record/type/type_map.rb +11 -15
  202. data/lib/active_record/type/unsigned_integer.rb +15 -0
  203. data/lib/active_record/type_caster.rb +2 -2
  204. data/lib/active_record/type_caster/connection.rb +8 -6
  205. data/lib/active_record/type_caster/map.rb +3 -1
  206. data/lib/active_record/validations.rb +4 -4
  207. data/lib/active_record/validations/associated.rb +1 -1
  208. data/lib/active_record/validations/presence.rb +2 -2
  209. data/lib/active_record/validations/uniqueness.rb +8 -39
  210. data/lib/active_record/version.rb +1 -1
  211. data/lib/rails/generators/active_record.rb +4 -4
  212. data/lib/rails/generators/active_record/migration.rb +2 -2
  213. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
  214. data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
  215. metadata +22 -13
  216. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -1,4 +1,4 @@
1
- require 'set'
1
+ require "set"
2
2
 
3
3
  module ActiveRecord
4
4
  module AttributeMethods
@@ -9,7 +9,7 @@ module ActiveRecord
9
9
  # available.
10
10
  def to_key
11
11
  sync_with_transaction_state
12
- key = self.id
12
+ key = id
13
13
  [key] if key
14
14
  end
15
15
 
@@ -45,97 +45,102 @@ module ActiveRecord
45
45
  attribute_was(self.class.primary_key)
46
46
  end
47
47
 
48
- protected
49
-
50
- def attribute_method?(attr_name)
51
- attr_name == 'id' || super
48
+ def id_in_database
49
+ sync_with_transaction_state
50
+ attribute_in_database(self.class.primary_key)
52
51
  end
53
52
 
54
- module ClassMethods
55
- def define_method_attribute(attr_name)
56
- super
53
+ private
57
54
 
58
- if attr_name == primary_key && attr_name != 'id'
59
- generated_attribute_methods.send(:alias_method, :id, primary_key)
60
- end
55
+ def attribute_method?(attr_name)
56
+ attr_name == "id" || super
61
57
  end
62
58
 
63
- ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was).to_set
59
+ module ClassMethods
60
+ def define_method_attribute(attr_name)
61
+ super
64
62
 
65
- def dangerous_attribute_method?(method_name)
66
- super && !ID_ATTRIBUTE_METHODS.include?(method_name)
67
- end
63
+ if attr_name == primary_key && attr_name != "id"
64
+ generated_attribute_methods.send(:alias_method, :id, primary_key)
65
+ end
66
+ end
68
67
 
69
- # Defines the primary key field -- can be overridden in subclasses.
70
- # Overwriting will negate any effect of the +primary_key_prefix_type+
71
- # setting, though.
72
- def primary_key
73
- @primary_key = reset_primary_key unless defined? @primary_key
74
- @primary_key
75
- end
68
+ ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was id_in_database).to_set
76
69
 
77
- # Returns a quoted version of the primary key name, used to construct
78
- # SQL statements.
79
- def quoted_primary_key
80
- @quoted_primary_key ||= connection.quote_column_name(primary_key)
81
- end
70
+ def dangerous_attribute_method?(method_name)
71
+ super && !ID_ATTRIBUTE_METHODS.include?(method_name)
72
+ end
82
73
 
83
- def reset_primary_key #:nodoc:
84
- if self == base_class
85
- self.primary_key = get_primary_key(base_class.name)
86
- else
87
- self.primary_key = base_class.primary_key
74
+ # Defines the primary key field -- can be overridden in subclasses.
75
+ # Overwriting will negate any effect of the +primary_key_prefix_type+
76
+ # setting, though.
77
+ def primary_key
78
+ @primary_key = reset_primary_key unless defined? @primary_key
79
+ @primary_key
88
80
  end
89
- end
90
81
 
91
- def get_primary_key(base_name) #:nodoc:
92
- if base_name && primary_key_prefix_type == :table_name
93
- base_name.foreign_key(false)
94
- elsif base_name && primary_key_prefix_type == :table_name_with_underscore
95
- base_name.foreign_key
96
- else
97
- if ActiveRecord::Base != self && table_exists?
98
- pk = connection.schema_cache.primary_keys(table_name)
99
- suppress_composite_primary_key(pk)
82
+ # Returns a quoted version of the primary key name, used to construct
83
+ # SQL statements.
84
+ def quoted_primary_key
85
+ @quoted_primary_key ||= connection.quote_column_name(primary_key)
86
+ end
87
+
88
+ def reset_primary_key #:nodoc:
89
+ if self == base_class
90
+ self.primary_key = get_primary_key(base_class.name)
100
91
  else
101
- 'id'
92
+ self.primary_key = base_class.primary_key
102
93
  end
103
94
  end
104
- end
105
95
 
106
- # Sets the name of the primary key column.
107
- #
108
- # class Project < ActiveRecord::Base
109
- # self.primary_key = 'sysid'
110
- # end
111
- #
112
- # You can also define the #primary_key method yourself:
113
- #
114
- # class Project < ActiveRecord::Base
115
- # def self.primary_key
116
- # 'foo_' + super
117
- # end
118
- # end
119
- #
120
- # Project.primary_key # => "foo_id"
121
- def primary_key=(value)
122
- @primary_key = value && value.to_s
123
- @quoted_primary_key = nil
124
- @attributes_builder = nil
125
- end
96
+ def get_primary_key(base_name) #:nodoc:
97
+ if base_name && primary_key_prefix_type == :table_name
98
+ base_name.foreign_key(false)
99
+ elsif base_name && primary_key_prefix_type == :table_name_with_underscore
100
+ base_name.foreign_key
101
+ else
102
+ if ActiveRecord::Base != self && table_exists?
103
+ pk = connection.schema_cache.primary_keys(table_name)
104
+ suppress_composite_primary_key(pk)
105
+ else
106
+ "id"
107
+ end
108
+ end
109
+ end
110
+
111
+ # Sets the name of the primary key column.
112
+ #
113
+ # class Project < ActiveRecord::Base
114
+ # self.primary_key = 'sysid'
115
+ # end
116
+ #
117
+ # You can also define the #primary_key method yourself:
118
+ #
119
+ # class Project < ActiveRecord::Base
120
+ # def self.primary_key
121
+ # 'foo_' + super
122
+ # end
123
+ # end
124
+ #
125
+ # Project.primary_key # => "foo_id"
126
+ def primary_key=(value)
127
+ @primary_key = value && value.to_s
128
+ @quoted_primary_key = nil
129
+ @attributes_builder = nil
130
+ end
126
131
 
127
- private
132
+ private
128
133
 
129
- def suppress_composite_primary_key(pk)
130
- return pk unless pk.is_a?(Array)
134
+ def suppress_composite_primary_key(pk)
135
+ return pk unless pk.is_a?(Array)
131
136
 
132
- warn <<-WARNING.strip_heredoc
133
- WARNING: Active Record does not support composite primary key.
137
+ warn <<-WARNING.strip_heredoc
138
+ WARNING: Active Record does not support composite primary key.
134
139
 
135
- #{table_name} has composite primary key. Composite primary key is ignored.
136
- WARNING
140
+ #{table_name} has composite primary key. Composite primary key is ignored.
141
+ WARNING
142
+ end
137
143
  end
138
- end
139
144
  end
140
145
  end
141
146
  end
@@ -4,51 +4,56 @@ module ActiveRecord
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  module ClassMethods
7
- protected
7
+ private
8
8
 
9
- # We want to generate the methods via module_eval rather than
10
- # define_method, because define_method is slower on dispatch.
11
- # Evaluating many similar methods may use more memory as the instruction
12
- # sequences are duplicated and cached (in MRI). define_method may
13
- # be slower on dispatch, but if you're careful about the closure
14
- # created, then define_method will consume much less memory.
15
- #
16
- # But sometimes the database might return columns with
17
- # characters that are not allowed in normal method names (like
18
- # 'my_column(omg)'. So to work around this we first define with
19
- # the __temp__ identifier, and then use alias method to rename
20
- # it to what we want.
21
- #
22
- # We are also defining a constant to hold the frozen string of
23
- # the attribute name. Using a constant means that we do not have
24
- # to allocate an object on each call to the attribute method.
25
- # Making it frozen means that it doesn't get duped when used to
26
- # key the @attributes in read_attribute.
27
- def define_method_attribute(name)
28
- safe_name = name.unpack('h*'.freeze).first
29
- temp_method = "__temp__#{safe_name}"
9
+ # We want to generate the methods via module_eval rather than
10
+ # define_method, because define_method is slower on dispatch.
11
+ # Evaluating many similar methods may use more memory as the instruction
12
+ # sequences are duplicated and cached (in MRI). define_method may
13
+ # be slower on dispatch, but if you're careful about the closure
14
+ # created, then define_method will consume much less memory.
15
+ #
16
+ # But sometimes the database might return columns with
17
+ # characters that are not allowed in normal method names (like
18
+ # 'my_column(omg)'. So to work around this we first define with
19
+ # the __temp__ identifier, and then use alias method to rename
20
+ # it to what we want.
21
+ #
22
+ # We are also defining a constant to hold the frozen string of
23
+ # the attribute name. Using a constant means that we do not have
24
+ # to allocate an object on each call to the attribute method.
25
+ # Making it frozen means that it doesn't get duped when used to
26
+ # key the @attributes in read_attribute.
27
+ def define_method_attribute(name)
28
+ safe_name = name.unpack("h*".freeze).first
29
+ temp_method = "__temp__#{safe_name}"
30
30
 
31
- ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
31
+ ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
32
32
 
33
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
34
- def #{temp_method}
35
- name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
36
- _read_attribute(name) { |n| missing_attribute(n, caller) }
37
- end
38
- STR
33
+ generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
34
+ def #{temp_method}
35
+ name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
36
+ _read_attribute(name) { |n| missing_attribute(n, caller) }
37
+ end
38
+ STR
39
39
 
40
- generated_attribute_methods.module_eval do
41
- alias_method name, temp_method
42
- undef_method temp_method
40
+ generated_attribute_methods.module_eval do
41
+ alias_method name, temp_method
42
+ undef_method temp_method
43
+ end
43
44
  end
44
- end
45
45
  end
46
46
 
47
47
  # Returns the value of the attribute identified by <tt>attr_name</tt> after
48
48
  # it has been typecast (for example, "2004-12-12" in a date column is cast
49
49
  # to a date object, like Date.new(2004, 12, 12)).
50
50
  def read_attribute(attr_name, &block)
51
- name = attr_name.to_s
51
+ name = if self.class.attribute_alias?(attr_name)
52
+ self.class.attribute_alias(attr_name).to_s
53
+ else
54
+ attr_name.to_s
55
+ end
56
+
52
57
  name = self.class.primary_key if name == "id".freeze && self.class.primary_key
53
58
  _read_attribute(name, &block)
54
59
  end
@@ -69,7 +74,6 @@ module ActiveRecord
69
74
 
70
75
  alias :attribute :_read_attribute
71
76
  private :attribute
72
-
73
77
  end
74
78
  end
75
79
  end
@@ -26,7 +26,7 @@ module ActiveRecord
26
26
  # ==== Parameters
27
27
  #
28
28
  # * +attr_name+ - The field name that should be serialized.
29
- # * +class_name_or_coder+ - Optional, a coder object, which responds to `.load` / `.dump`
29
+ # * +class_name_or_coder+ - Optional, a coder object, which responds to +.load+ and +.dump+
30
30
  # or a class name that the object type should be equal to.
31
31
  #
32
32
  # ==== Example
@@ -50,12 +50,12 @@ module ActiveRecord
50
50
  # to ensure special objects (e.g. Active Record models) are dumped correctly
51
51
  # using the #as_json hook.
52
52
  coder = if class_name_or_coder == ::JSON
53
- Coders::JSON
54
- elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) }
55
- class_name_or_coder
56
- else
57
- Coders::YAMLColumn.new(class_name_or_coder)
58
- end
53
+ Coders::JSON
54
+ elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) }
55
+ class_name_or_coder
56
+ else
57
+ Coders::YAMLColumn.new(attr_name, class_name_or_coder)
58
+ end
59
59
 
60
60
  decorate_attribute_type(attr_name, :serialize) do |type|
61
61
  Type::Serialized.new(type, coder)
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/string/strip'
2
-
3
1
  module ActiveRecord
4
2
  module AttributeMethods
5
3
  module TimeZoneConversion
@@ -26,31 +24,31 @@ module ActiveRecord
26
24
 
27
25
  private
28
26
 
29
- def convert_time_to_time_zone(value)
30
- return if value.nil?
27
+ def convert_time_to_time_zone(value)
28
+ return if value.nil?
31
29
 
32
- if value.acts_like?(:time)
33
- value.in_time_zone
34
- elsif value.is_a?(::Float)
35
- value
36
- else
37
- map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
30
+ if value.acts_like?(:time)
31
+ value.in_time_zone
32
+ elsif value.is_a?(::Float)
33
+ value
34
+ else
35
+ map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
36
+ end
38
37
  end
39
- end
40
38
 
41
- def set_time_zone_without_conversion(value)
42
- ::Time.zone.local_to_utc(value).in_time_zone if value
43
- end
39
+ def set_time_zone_without_conversion(value)
40
+ ::Time.zone.local_to_utc(value).try(:in_time_zone) if value
41
+ end
44
42
 
45
- def map_avoiding_infinite_recursion(value)
46
- map(value) do |v|
47
- if value.equal?(v)
48
- nil
49
- else
50
- yield(v)
43
+ def map_avoiding_infinite_recursion(value)
44
+ map(value) do |v|
45
+ if value.equal?(v)
46
+ nil
47
+ else
48
+ yield(v)
49
+ end
51
50
  end
52
51
  end
53
- end
54
52
  end
55
53
 
56
54
  extend ActiveSupport::Concern
@@ -63,53 +61,32 @@ module ActiveRecord
63
61
  self.skip_time_zone_conversion_for_attributes = []
64
62
 
65
63
  class_attribute :time_zone_aware_types, instance_writer: false
66
- self.time_zone_aware_types = [:datetime, :not_explicitly_configured]
64
+ self.time_zone_aware_types = [:datetime, :time]
67
65
  end
68
66
 
69
67
  module ClassMethods
70
68
  private
71
69
 
72
- def inherited(subclass)
73
- # We need to apply this decorator here, rather than on module inclusion. The closure
74
- # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
75
- # sub class being decorated. As such, changes to `time_zone_aware_attributes`, or
76
- # `skip_time_zone_conversion_for_attributes` would not be picked up.
77
- subclass.class_eval do
78
- matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) }
79
- decorate_matching_attribute_types(matcher, :_time_zone_conversion) do |type|
80
- TimeZoneConverter.new(type)
70
+ def inherited(subclass)
71
+ super
72
+ # We need to apply this decorator here, rather than on module inclusion. The closure
73
+ # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
74
+ # sub class being decorated. As such, changes to `time_zone_aware_attributes`, or
75
+ # `skip_time_zone_conversion_for_attributes` would not be picked up.
76
+ subclass.class_eval do
77
+ matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) }
78
+ decorate_matching_attribute_types(matcher, :_time_zone_conversion) do |type|
79
+ TimeZoneConverter.new(type)
80
+ end
81
81
  end
82
82
  end
83
- super
84
- end
85
-
86
- def create_time_zone_conversion_attribute?(name, cast_type)
87
- enabled_for_column = time_zone_aware_attributes &&
88
- !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym)
89
- result = enabled_for_column &&
90
- time_zone_aware_types.include?(cast_type.type)
91
-
92
- if enabled_for_column &&
93
- !result &&
94
- cast_type.type == :time &&
95
- time_zone_aware_types.include?(:not_explicitly_configured)
96
- ActiveSupport::Deprecation.warn(<<-MESSAGE.strip_heredoc)
97
- Time columns will become time zone aware in Rails 5.1. This
98
- still causes `String`s to be parsed as if they were in `Time.zone`,
99
- and `Time`s to be converted to `Time.zone`.
100
83
 
101
- To keep the old behavior, you must add the following to your initializer:
84
+ def create_time_zone_conversion_attribute?(name, cast_type)
85
+ enabled_for_column = time_zone_aware_attributes &&
86
+ !skip_time_zone_conversion_for_attributes.include?(name.to_sym)
102
87
 
103
- config.active_record.time_zone_aware_types = [:datetime]
104
-
105
- To use the new behavior, add the following:
106
-
107
- config.active_record.time_zone_aware_types = [:datetime, :time]
108
- MESSAGE
88
+ enabled_for_column && time_zone_aware_types.include?(cast_type.type)
109
89
  end
110
-
111
- result
112
- end
113
90
  end
114
91
  end
115
92
  end
@@ -8,28 +8,34 @@ module ActiveRecord
8
8
  end
9
9
 
10
10
  module ClassMethods
11
- protected
12
-
13
- def define_method_attribute=(name)
14
- safe_name = name.unpack('h*'.freeze).first
15
- ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
16
-
17
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
18
- def __temp__#{safe_name}=(value)
19
- name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
20
- write_attribute(name, value)
21
- end
22
- alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
23
- undef_method :__temp__#{safe_name}=
24
- STR
25
- end
11
+ private
12
+
13
+ def define_method_attribute=(name)
14
+ safe_name = name.unpack("h*".freeze).first
15
+ ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
16
+
17
+ generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
18
+ def __temp__#{safe_name}=(value)
19
+ name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
20
+ write_attribute(name, value)
21
+ end
22
+ alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
23
+ undef_method :__temp__#{safe_name}=
24
+ STR
25
+ end
26
26
  end
27
27
 
28
28
  # Updates the attribute identified by <tt>attr_name</tt> with the
29
29
  # specified +value+. Empty strings for Integer and Float columns are
30
30
  # turned into +nil+.
31
31
  def write_attribute(attr_name, value)
32
- write_attribute_with_type_cast(attr_name, value, true)
32
+ name = if self.class.attribute_alias?(attr_name)
33
+ self.class.attribute_alias(attr_name).to_s
34
+ else
35
+ attr_name.to_s
36
+ end
37
+
38
+ write_attribute_with_type_cast(name, value, true)
33
39
  end
34
40
 
35
41
  def raw_write_attribute(attr_name, value) # :nodoc:
@@ -37,23 +43,23 @@ module ActiveRecord
37
43
  end
38
44
 
39
45
  private
40
- # Handle *= for method_missing.
41
- def attribute=(attribute_name, value)
42
- write_attribute(attribute_name, value)
43
- end
46
+ # Handle *= for method_missing.
47
+ def attribute=(attribute_name, value)
48
+ write_attribute(attribute_name, value)
49
+ end
44
50
 
45
- def write_attribute_with_type_cast(attr_name, value, should_type_cast)
46
- attr_name = attr_name.to_s
47
- attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
51
+ def write_attribute_with_type_cast(attr_name, value, should_type_cast)
52
+ attr_name = attr_name.to_s
53
+ attr_name = self.class.primary_key if attr_name == "id" && self.class.primary_key
48
54
 
49
- if should_type_cast
50
- @attributes.write_from_user(attr_name, value)
51
- else
52
- @attributes.write_cast_value(attr_name, value)
53
- end
55
+ if should_type_cast
56
+ @attributes.write_from_user(attr_name, value)
57
+ else
58
+ @attributes.write_cast_value(attr_name, value)
59
+ end
54
60
 
55
- value
56
- end
61
+ value
62
+ end
57
63
  end
58
64
  end
59
65
  end