activerecord 6.0.4.1 → 6.1.0.rc1

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 (242) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +767 -851
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -3
  5. data/lib/active_record.rb +7 -14
  6. data/lib/active_record/aggregations.rb +1 -1
  7. data/lib/active_record/association_relation.rb +22 -14
  8. data/lib/active_record/associations.rb +114 -11
  9. data/lib/active_record/associations/alias_tracker.rb +19 -15
  10. data/lib/active_record/associations/association.rb +39 -27
  11. data/lib/active_record/associations/association_scope.rb +11 -15
  12. data/lib/active_record/associations/belongs_to_association.rb +15 -5
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  14. data/lib/active_record/associations/builder/association.rb +9 -3
  15. data/lib/active_record/associations/builder/belongs_to.rb +10 -7
  16. data/lib/active_record/associations/builder/collection_association.rb +5 -4
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
  18. data/lib/active_record/associations/builder/has_many.rb +6 -2
  19. data/lib/active_record/associations/builder/has_one.rb +11 -14
  20. data/lib/active_record/associations/builder/singular_association.rb +1 -1
  21. data/lib/active_record/associations/collection_association.rb +19 -13
  22. data/lib/active_record/associations/collection_proxy.rb +12 -5
  23. data/lib/active_record/associations/foreign_association.rb +13 -0
  24. data/lib/active_record/associations/has_many_association.rb +24 -2
  25. data/lib/active_record/associations/has_many_through_association.rb +10 -4
  26. data/lib/active_record/associations/has_one_association.rb +15 -1
  27. data/lib/active_record/associations/join_dependency.rb +63 -49
  28. data/lib/active_record/associations/join_dependency/join_association.rb +29 -14
  29. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  30. data/lib/active_record/associations/preloader.rb +5 -3
  31. data/lib/active_record/associations/preloader/association.rb +13 -5
  32. data/lib/active_record/associations/preloader/through_association.rb +1 -1
  33. data/lib/active_record/associations/singular_association.rb +1 -1
  34. data/lib/active_record/attribute_assignment.rb +10 -8
  35. data/lib/active_record/attribute_methods.rb +52 -48
  36. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
  37. data/lib/active_record/attribute_methods/dirty.rb +1 -11
  38. data/lib/active_record/attribute_methods/primary_key.rb +6 -2
  39. data/lib/active_record/attribute_methods/query.rb +3 -6
  40. data/lib/active_record/attribute_methods/read.rb +8 -11
  41. data/lib/active_record/attribute_methods/serialization.rb +4 -4
  42. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
  43. data/lib/active_record/attribute_methods/write.rb +12 -20
  44. data/lib/active_record/attributes.rb +27 -7
  45. data/lib/active_record/autosave_association.rb +47 -30
  46. data/lib/active_record/base.rb +2 -14
  47. data/lib/active_record/callbacks.rb +32 -22
  48. data/lib/active_record/coders/yaml_column.rb +1 -1
  49. data/lib/active_record/connection_adapters.rb +50 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +180 -134
  51. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  52. data/lib/active_record/connection_adapters/abstract/database_statements.rb +65 -22
  53. data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -7
  54. data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
  55. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  56. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
  57. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +110 -30
  58. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +224 -85
  60. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -24
  61. data/lib/active_record/connection_adapters/abstract_adapter.rb +31 -70
  62. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
  63. data/lib/active_record/connection_adapters/column.rb +15 -1
  64. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  65. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  66. data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -24
  67. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
  69. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +33 -6
  70. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  71. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  72. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +3 -3
  73. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  74. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
  75. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  76. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  77. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  78. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +12 -53
  79. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  80. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  81. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -10
  83. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  87. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
  89. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  90. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  91. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
  92. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
  93. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  94. data/lib/active_record/connection_adapters/postgresql_adapter.rb +72 -55
  95. data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
  96. data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
  97. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +30 -5
  98. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
  99. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  100. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
  101. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
  102. data/lib/active_record/connection_handling.rb +210 -71
  103. data/lib/active_record/core.rb +215 -49
  104. data/lib/active_record/database_configurations.rb +124 -85
  105. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  106. data/lib/active_record/database_configurations/database_config.rb +52 -9
  107. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  108. data/lib/active_record/database_configurations/url_config.rb +15 -40
  109. data/lib/active_record/delegated_type.rb +209 -0
  110. data/lib/active_record/destroy_association_async_job.rb +36 -0
  111. data/lib/active_record/enum.rb +33 -23
  112. data/lib/active_record/errors.rb +47 -12
  113. data/lib/active_record/explain.rb +9 -4
  114. data/lib/active_record/explain_subscriber.rb +1 -1
  115. data/lib/active_record/fixture_set/file.rb +10 -17
  116. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  117. data/lib/active_record/fixture_set/render_context.rb +1 -1
  118. data/lib/active_record/fixture_set/table_row.rb +2 -2
  119. data/lib/active_record/fixtures.rb +54 -8
  120. data/lib/active_record/gem_version.rb +3 -3
  121. data/lib/active_record/inheritance.rb +40 -18
  122. data/lib/active_record/insert_all.rb +32 -5
  123. data/lib/active_record/integration.rb +3 -5
  124. data/lib/active_record/internal_metadata.rb +15 -4
  125. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  126. data/lib/active_record/locking/optimistic.rb +13 -16
  127. data/lib/active_record/locking/pessimistic.rb +6 -2
  128. data/lib/active_record/log_subscriber.rb +26 -8
  129. data/lib/active_record/middleware/database_selector.rb +4 -1
  130. data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
  131. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  132. data/lib/active_record/migration.rb +113 -83
  133. data/lib/active_record/migration/command_recorder.rb +47 -27
  134. data/lib/active_record/migration/compatibility.rb +67 -17
  135. data/lib/active_record/model_schema.rb +88 -42
  136. data/lib/active_record/nested_attributes.rb +2 -3
  137. data/lib/active_record/no_touching.rb +1 -1
  138. data/lib/active_record/persistence.rb +50 -45
  139. data/lib/active_record/query_cache.rb +15 -5
  140. data/lib/active_record/querying.rb +11 -6
  141. data/lib/active_record/railtie.rb +64 -44
  142. data/lib/active_record/railties/databases.rake +253 -98
  143. data/lib/active_record/readonly_attributes.rb +4 -0
  144. data/lib/active_record/reflection.rb +59 -44
  145. data/lib/active_record/relation.rb +90 -64
  146. data/lib/active_record/relation/batches.rb +38 -31
  147. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  148. data/lib/active_record/relation/calculations.rb +100 -43
  149. data/lib/active_record/relation/finder_methods.rb +44 -14
  150. data/lib/active_record/relation/from_clause.rb +1 -1
  151. data/lib/active_record/relation/merger.rb +20 -23
  152. data/lib/active_record/relation/predicate_builder.rb +57 -33
  153. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  154. data/lib/active_record/relation/predicate_builder/association_query_value.rb +2 -2
  155. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
  156. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  157. data/lib/active_record/relation/query_methods.rb +319 -196
  158. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  159. data/lib/active_record/relation/spawn_methods.rb +6 -5
  160. data/lib/active_record/relation/where_clause.rb +104 -57
  161. data/lib/active_record/result.rb +41 -33
  162. data/lib/active_record/runtime_registry.rb +2 -2
  163. data/lib/active_record/sanitization.rb +6 -17
  164. data/lib/active_record/schema_dumper.rb +34 -4
  165. data/lib/active_record/schema_migration.rb +0 -4
  166. data/lib/active_record/scoping/named.rb +1 -17
  167. data/lib/active_record/secure_token.rb +16 -8
  168. data/lib/active_record/serialization.rb +5 -3
  169. data/lib/active_record/signed_id.rb +116 -0
  170. data/lib/active_record/statement_cache.rb +20 -4
  171. data/lib/active_record/store.rb +2 -2
  172. data/lib/active_record/suppressor.rb +2 -2
  173. data/lib/active_record/table_metadata.rb +36 -52
  174. data/lib/active_record/tasks/database_tasks.rb +139 -113
  175. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
  176. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
  177. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
  178. data/lib/active_record/test_databases.rb +5 -4
  179. data/lib/active_record/test_fixtures.rb +36 -33
  180. data/lib/active_record/timestamp.rb +4 -6
  181. data/lib/active_record/touch_later.rb +21 -21
  182. data/lib/active_record/transactions.rb +15 -64
  183. data/lib/active_record/type.rb +8 -1
  184. data/lib/active_record/type/serialized.rb +6 -2
  185. data/lib/active_record/type_caster/connection.rb +0 -1
  186. data/lib/active_record/type_caster/map.rb +8 -5
  187. data/lib/active_record/validations.rb +1 -0
  188. data/lib/active_record/validations/associated.rb +1 -1
  189. data/lib/active_record/validations/numericality.rb +35 -0
  190. data/lib/active_record/validations/uniqueness.rb +24 -4
  191. data/lib/arel.rb +5 -13
  192. data/lib/arel/attributes/attribute.rb +4 -0
  193. data/lib/arel/collectors/bind.rb +5 -0
  194. data/lib/arel/collectors/composite.rb +8 -0
  195. data/lib/arel/collectors/sql_string.rb +7 -0
  196. data/lib/arel/collectors/substitute_binds.rb +7 -0
  197. data/lib/arel/nodes.rb +3 -1
  198. data/lib/arel/nodes/binary.rb +82 -8
  199. data/lib/arel/nodes/bind_param.rb +8 -0
  200. data/lib/arel/nodes/casted.rb +21 -9
  201. data/lib/arel/nodes/equality.rb +6 -9
  202. data/lib/arel/nodes/grouping.rb +3 -0
  203. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  204. data/lib/arel/nodes/in.rb +8 -1
  205. data/lib/arel/nodes/infix_operation.rb +13 -1
  206. data/lib/arel/nodes/join_source.rb +1 -1
  207. data/lib/arel/nodes/node.rb +7 -6
  208. data/lib/arel/nodes/ordering.rb +27 -0
  209. data/lib/arel/nodes/sql_literal.rb +3 -0
  210. data/lib/arel/nodes/table_alias.rb +7 -3
  211. data/lib/arel/nodes/unary.rb +0 -1
  212. data/lib/arel/predications.rb +12 -18
  213. data/lib/arel/select_manager.rb +1 -2
  214. data/lib/arel/table.rb +13 -5
  215. data/lib/arel/visitors.rb +0 -7
  216. data/lib/arel/visitors/dot.rb +14 -2
  217. data/lib/arel/visitors/mysql.rb +11 -1
  218. data/lib/arel/visitors/postgresql.rb +15 -4
  219. data/lib/arel/visitors/to_sql.rb +89 -78
  220. data/lib/rails/generators/active_record/migration.rb +6 -1
  221. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  222. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  223. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
  224. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  225. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  226. metadata +30 -31
  227. data/lib/active_record/advisory_lock_base.rb +0 -18
  228. data/lib/active_record/attribute_decorators.rb +0 -88
  229. data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
  230. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  231. data/lib/active_record/define_callbacks.rb +0 -22
  232. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  233. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  234. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  235. data/lib/arel/attributes.rb +0 -22
  236. data/lib/arel/visitors/depth_first.rb +0 -203
  237. data/lib/arel/visitors/ibm_db.rb +0 -34
  238. data/lib/arel/visitors/informix.rb +0 -62
  239. data/lib/arel/visitors/mssql.rb +0 -156
  240. data/lib/arel/visitors/oracle.rb +0 -158
  241. data/lib/arel/visitors/oracle12.rb +0 -65
  242. data/lib/arel/visitors/where_sql.rb +0 -22
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  # association.
18
18
  attr_reader :base_klass, :children
19
19
 
20
- delegate :table_name, :column_names, :primary_key, to: :base_klass
20
+ delegate :table_name, :column_names, :primary_key, :attribute_types, to: :base_klass
21
21
 
22
22
  def initialize(base_klass, children)
23
23
  @base_klass = base_klass
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/enumerable"
4
+
3
5
  module ActiveRecord
4
6
  module Associations
5
7
  # Implements the details of eager loading of Active Record associations.
@@ -58,7 +60,7 @@ module ActiveRecord
58
60
  # == Parameters
59
61
  # +records+ is an array of ActiveRecord::Base. This array needs not be flat,
60
62
  # i.e. +records+ itself may also contain arrays of records. In any case,
61
- # +preload_associations+ will preload the all associations records by
63
+ # +preload_associations+ will preload all associations records by
62
64
  # flattening +records+.
63
65
  #
64
66
  # +associations+ specifies one or more associations that you want to
@@ -175,8 +177,8 @@ module ActiveRecord
175
177
  end
176
178
 
177
179
  def records_by_owner
178
- @records_by_owner ||= owners.each_with_object({}) do |owner, result|
179
- result[owner] = Array(owner.association(reflection.name).target)
180
+ @records_by_owner ||= owners.index_with do |owner|
181
+ Array(owner.association(reflection.name).target)
180
182
  end
181
183
  end
182
184
 
@@ -45,18 +45,18 @@ module ActiveRecord
45
45
  raw_records = owner_keys.empty? ? [] : records_for(owner_keys)
46
46
 
47
47
  @preloaded_records = raw_records.select do |record|
48
- assignments = []
48
+ assignments = false
49
49
 
50
50
  owners_by_key[convert_key(record[association_key_name])].each do |owner|
51
51
  entries = (@records_by_owner[owner] ||= [])
52
52
 
53
53
  if reflection.collection? || entries.empty?
54
54
  entries << record
55
- assignments << record
55
+ assignments = true
56
56
  end
57
57
  end
58
58
 
59
- !assignments.empty?
59
+ assignments
60
60
  end
61
61
  end
62
62
 
@@ -142,8 +142,16 @@ module ActiveRecord
142
142
  end
143
143
 
144
144
  scope.merge!(reflection_scope) unless reflection_scope.empty_scope?
145
- scope.merge!(preload_scope) if preload_scope
146
- scope
145
+
146
+ if preload_scope && !preload_scope.empty_scope?
147
+ scope.merge!(preload_scope)
148
+ end
149
+
150
+ if preload_scope && preload_scope.strict_loading_value
151
+ scope.strict_loading
152
+ else
153
+ scope
154
+ end
147
155
  end
148
156
  end
149
157
  end
@@ -90,7 +90,7 @@ module ActiveRecord
90
90
  end
91
91
 
92
92
  if values[:references] && !values[:references].empty?
93
- scope.references!(values[:references])
93
+ scope.references_values |= values[:references]
94
94
  else
95
95
  scope.references!(source_reflection.table_name)
96
96
  end
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  replace(record)
18
18
  end
19
19
 
20
- def build(attributes = {}, &block)
20
+ def build(attributes = nil, &block)
21
21
  record = build_record(attributes, &block)
22
22
  set_new_record(record)
23
23
  record
@@ -8,20 +8,22 @@ module ActiveRecord
8
8
 
9
9
  private
10
10
  def _assign_attributes(attributes)
11
- multi_parameter_attributes = {}
12
- nested_parameter_attributes = {}
11
+ multi_parameter_attributes = nested_parameter_attributes = nil
13
12
 
14
13
  attributes.each do |k, v|
15
- if k.include?("(")
16
- multi_parameter_attributes[k] = attributes.delete(k)
14
+ key = k.to_s
15
+
16
+ if key.include?("(")
17
+ (multi_parameter_attributes ||= {})[key] = v
17
18
  elsif v.is_a?(Hash)
18
- nested_parameter_attributes[k] = attributes.delete(k)
19
+ (nested_parameter_attributes ||= {})[key] = v
20
+ else
21
+ _assign_attribute(key, v)
19
22
  end
20
23
  end
21
- super(attributes)
22
24
 
23
- assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
24
- assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
25
+ assign_nested_parameter_attributes(nested_parameter_attributes) if nested_parameter_attributes
26
+ assign_multiparameter_attributes(multi_parameter_attributes) if multi_parameter_attributes
25
27
  end
26
28
 
27
29
  # Assign any deferred nested attributes after the base attributes have been set.
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "mutex_m"
4
+ require "active_support/core_ext/enumerable"
4
5
 
5
6
  module ActiveRecord
6
7
  # = Active Record Attribute Methods
@@ -18,8 +19,6 @@ module ActiveRecord
18
19
  include TimeZoneConversion
19
20
  include Dirty
20
21
  include Serialization
21
-
22
- delegate :column_for_attribute, to: :class
23
22
  end
24
23
 
25
24
  RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
@@ -28,6 +27,17 @@ module ActiveRecord
28
27
  include Mutex_m
29
28
  end
30
29
 
30
+ class << self
31
+ def dangerous_attribute_methods # :nodoc:
32
+ @dangerous_attribute_methods ||= (
33
+ Base.instance_methods +
34
+ Base.private_instance_methods -
35
+ Base.superclass.instance_methods -
36
+ Base.superclass.private_instance_methods
37
+ ).map { |m| -m.to_s }.to_set.freeze
38
+ end
39
+ end
40
+
31
41
  module ClassMethods
32
42
  def inherited(child_class) #:nodoc:
33
43
  child_class.initialize_generated_modules
@@ -97,7 +107,7 @@ module ActiveRecord
97
107
  # A method name is 'dangerous' if it is already (re)defined by Active Record, but
98
108
  # not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
99
109
  def dangerous_attribute_method?(name) # :nodoc:
100
- method_defined_within?(name, Base)
110
+ ::ActiveRecord::AttributeMethods.dangerous_attribute_methods.include?(name.to_s)
101
111
  end
102
112
 
103
113
  def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
@@ -115,13 +125,11 @@ module ActiveRecord
115
125
  # A class method is 'dangerous' if it is already (re)defined by Active Record, but
116
126
  # not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
117
127
  def dangerous_class_method?(method_name)
118
- RESTRICTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
119
- end
128
+ return true if RESTRICTED_CLASS_METHODS.include?(method_name.to_s)
120
129
 
121
- def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
122
- if klass.respond_to?(name, true)
123
- if superklass.respond_to?(name, true)
124
- klass.method(name).owner != superklass.method(name).owner
130
+ if Base.respond_to?(method_name, true)
131
+ if Object.respond_to?(method_name, true)
132
+ Base.method(method_name).owner != Object.method(method_name).owner
125
133
  else
126
134
  true
127
135
  end
@@ -140,7 +148,7 @@ module ActiveRecord
140
148
  # Person.attribute_method?(:age=) # => true
141
149
  # Person.attribute_method?(:nothing) # => false
142
150
  def attribute_method?(attribute)
143
- super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, "")))
151
+ super || (table_exists? && column_names.include?(attribute.to_s.delete_suffix("=")))
144
152
  end
145
153
 
146
154
  # Returns an array of column names as strings if it's not an abstract class and
@@ -156,39 +164,27 @@ module ActiveRecord
156
164
  attribute_types.keys
157
165
  else
158
166
  []
159
- end
167
+ end.freeze
160
168
  end
161
169
 
162
170
  # Returns true if the given attribute exists, otherwise false.
163
171
  #
164
172
  # class Person < ActiveRecord::Base
173
+ # alias_attribute :new_name, :name
165
174
  # end
166
175
  #
167
- # Person.has_attribute?('name') # => true
168
- # Person.has_attribute?(:age) # => true
169
- # Person.has_attribute?(:nothing) # => false
176
+ # Person.has_attribute?('name') # => true
177
+ # Person.has_attribute?('new_name') # => true
178
+ # Person.has_attribute?(:age) # => true
179
+ # Person.has_attribute?(:nothing) # => false
170
180
  def has_attribute?(attr_name)
171
- attribute_types.key?(attr_name.to_s)
181
+ attr_name = attr_name.to_s
182
+ attr_name = attribute_aliases[attr_name] || attr_name
183
+ attribute_types.key?(attr_name)
172
184
  end
173
185
 
174
- # Returns the column object for the named attribute.
175
- # Returns a +ActiveRecord::ConnectionAdapters::NullColumn+ if the
176
- # named attribute does not exist.
177
- #
178
- # class Person < ActiveRecord::Base
179
- # end
180
- #
181
- # person = Person.new
182
- # person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
183
- # # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
184
- #
185
- # person.column_for_attribute(:nothing)
186
- # # => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
187
- def column_for_attribute(name)
188
- name = name.to_s
189
- columns_hash.fetch(name) do
190
- ConnectionAdapters::NullColumn.new(name)
191
- end
186
+ def _has_attribute?(attr_name) # :nodoc:
187
+ attribute_types.key?(attr_name)
192
188
  end
193
189
  end
194
190
 
@@ -217,7 +213,7 @@ module ActiveRecord
217
213
  # have been allocated but not yet initialized.
218
214
  if defined?(@attributes)
219
215
  if name = self.class.symbol_column_to_string(name.to_sym)
220
- return has_attribute?(name)
216
+ return _has_attribute?(name)
221
217
  end
222
218
  end
223
219
 
@@ -227,14 +223,22 @@ module ActiveRecord
227
223
  # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
228
224
  #
229
225
  # class Person < ActiveRecord::Base
226
+ # alias_attribute :new_name, :name
230
227
  # end
231
228
  #
232
229
  # person = Person.new
233
- # person.has_attribute?(:name) # => true
234
- # person.has_attribute?('age') # => true
235
- # person.has_attribute?(:nothing) # => false
230
+ # person.has_attribute?(:name) # => true
231
+ # person.has_attribute?(:new_name) # => true
232
+ # person.has_attribute?('age') # => true
233
+ # person.has_attribute?(:nothing) # => false
236
234
  def has_attribute?(attr_name)
237
- @attributes.key?(attr_name.to_s)
235
+ attr_name = attr_name.to_s
236
+ attr_name = self.class.attribute_aliases[attr_name] || attr_name
237
+ @attributes.key?(attr_name)
238
+ end
239
+
240
+ def _has_attribute?(attr_name) # :nodoc:
241
+ @attributes.key?(attr_name)
238
242
  end
239
243
 
240
244
  # Returns an array of names for the attributes available on this object.
@@ -278,6 +282,8 @@ module ActiveRecord
278
282
  # person.attribute_for_inspect(:tag_ids)
279
283
  # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
280
284
  def attribute_for_inspect(attr_name)
285
+ attr_name = attr_name.to_s
286
+ attr_name = self.class.attribute_aliases[attr_name] || attr_name
281
287
  value = _read_attribute(attr_name)
282
288
  format_for_inspect(value)
283
289
  end
@@ -297,8 +303,10 @@ module ActiveRecord
297
303
  # task.is_done = true
298
304
  # task.attribute_present?(:title) # => true
299
305
  # task.attribute_present?(:is_done) # => true
300
- def attribute_present?(attribute)
301
- value = _read_attribute(attribute)
306
+ def attribute_present?(attr_name)
307
+ attr_name = attr_name.to_s
308
+ attr_name = self.class.attribute_aliases[attr_name] || attr_name
309
+ value = _read_attribute(attr_name)
302
310
  !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
303
311
  end
304
312
 
@@ -377,8 +385,8 @@ module ActiveRecord
377
385
  end
378
386
 
379
387
  def attributes_with_values(attribute_names)
380
- attribute_names.each_with_object({}) do |name, attrs|
381
- attrs[name] = _read_attribute(name)
388
+ attribute_names.index_with do |name|
389
+ _read_attribute(name)
382
390
  end
383
391
  end
384
392
 
@@ -386,7 +394,7 @@ module ActiveRecord
386
394
  def attributes_for_update(attribute_names)
387
395
  attribute_names &= self.class.column_names
388
396
  attribute_names.delete_if do |name|
389
- readonly_attribute?(name)
397
+ self.class.readonly_attribute?(name)
390
398
  end
391
399
  end
392
400
 
@@ -403,16 +411,12 @@ module ActiveRecord
403
411
  if value.is_a?(String) && value.length > 50
404
412
  "#{value[0, 50]}...".inspect
405
413
  elsif value.is_a?(Date) || value.is_a?(Time)
406
- %("#{value.to_s(:db)}")
414
+ %("#{value.to_s(:inspect)}")
407
415
  else
408
416
  value.inspect
409
417
  end
410
418
  end
411
419
 
412
- def readonly_attribute?(name)
413
- self.class.readonly_attributes.include?(name)
414
- end
415
-
416
420
  def pk_attribute?(name)
417
421
  name == @primary_key
418
422
  end
@@ -29,7 +29,7 @@ module ActiveRecord
29
29
  extend ActiveSupport::Concern
30
30
 
31
31
  included do
32
- attribute_method_suffix "_before_type_cast"
32
+ attribute_method_suffix "_before_type_cast", "_for_database"
33
33
  attribute_method_suffix "_came_from_user?"
34
34
  end
35
35
 
@@ -46,8 +46,10 @@ module ActiveRecord
46
46
  # task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
47
47
  # task.read_attribute_before_type_cast(:completed_on) # => "2012-10-21"
48
48
  def read_attribute_before_type_cast(attr_name)
49
- sync_with_transaction_state if @transaction_state&.finalized?
50
- @attributes[attr_name.to_s].value_before_type_cast
49
+ name = attr_name.to_s
50
+ name = self.class.attribute_aliases[name] || name
51
+
52
+ attribute_before_type_cast(name)
51
53
  end
52
54
 
53
55
  # Returns a hash of attributes before typecasting and deserialization.
@@ -61,19 +63,21 @@ module ActiveRecord
61
63
  # task.attributes_before_type_cast
62
64
  # # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
63
65
  def attributes_before_type_cast
64
- sync_with_transaction_state if @transaction_state&.finalized?
65
66
  @attributes.values_before_type_cast
66
67
  end
67
68
 
68
69
  private
69
70
  # Dispatch target for <tt>*_before_type_cast</tt> attribute methods.
70
- def attribute_before_type_cast(attribute_name)
71
- read_attribute_before_type_cast(attribute_name)
71
+ def attribute_before_type_cast(attr_name)
72
+ @attributes[attr_name].value_before_type_cast
73
+ end
74
+
75
+ def attribute_for_database(attr_name)
76
+ @attributes[attr_name].value_for_database
72
77
  end
73
78
 
74
- def attribute_came_from_user?(attribute_name)
75
- sync_with_transaction_state if @transaction_state&.finalized?
76
- @attributes[attribute_name].came_from_user?
79
+ def attribute_came_from_user?(attr_name)
80
+ @attributes[attr_name].came_from_user?
77
81
  end
78
82
  end
79
83
  end
@@ -89,7 +89,7 @@ module ActiveRecord
89
89
  # This method is useful in validations and before callbacks to determine
90
90
  # if the next call to +save+ will change a particular attribute. It can be
91
91
  # invoked as +will_save_change_to_name?+ instead of
92
- # <tt>will_save_change_to_attribute("name")</tt>.
92
+ # <tt>will_save_change_to_attribute?("name")</tt>.
93
93
  #
94
94
  # ==== Options
95
95
  #
@@ -156,16 +156,6 @@ module ActiveRecord
156
156
  end
157
157
 
158
158
  private
159
- def mutations_from_database
160
- sync_with_transaction_state if @transaction_state&.finalized?
161
- super
162
- end
163
-
164
- def mutations_before_last_save
165
- sync_with_transaction_state if @transaction_state&.finalized?
166
- super
167
- end
168
-
169
159
  def write_attribute_without_type_cast(attr_name, value)
170
160
  result = super
171
161
  clear_attribute_change(attr_name)
@@ -31,7 +31,7 @@ module ActiveRecord
31
31
 
32
32
  # Returns the primary key column's value before type cast.
33
33
  def id_before_type_cast
34
- read_attribute_before_type_cast(@primary_key)
34
+ attribute_before_type_cast(@primary_key)
35
35
  end
36
36
 
37
37
  # Returns the primary key column's previous value.
@@ -44,13 +44,17 @@ module ActiveRecord
44
44
  attribute_in_database(@primary_key)
45
45
  end
46
46
 
47
+ def id_for_database # :nodoc:
48
+ @attributes[@primary_key].value_for_database
49
+ end
50
+
47
51
  private
48
52
  def attribute_method?(attr_name)
49
53
  attr_name == "id" || super
50
54
  end
51
55
 
52
56
  module ClassMethods
53
- ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was id_in_database).to_set
57
+ ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was id_in_database id_for_database).to_set
54
58
 
55
59
  def instance_method_already_implemented?(method_name)
56
60
  super || primary_key && ID_ATTRIBUTE_METHODS.include?(method_name)
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  when false, nil then false
18
18
  else
19
19
  if !type_for_attribute(attr_name) { false }
20
- if Numeric === value || value !~ /[^0-9]/
20
+ if Numeric === value || !value.match?(/[^0-9]/)
21
21
  !value.to_i.zero?
22
22
  else
23
23
  return false if ActiveModel::Type::Boolean::FALSE_VALUES.include?(value)
@@ -31,11 +31,8 @@ module ActiveRecord
31
31
  end
32
32
  end
33
33
 
34
- private
35
- # Dispatch target for <tt>*?</tt> attribute methods.
36
- def attribute?(attribute_name)
37
- query_attribute(attribute_name)
38
- end
34
+ alias :attribute? :query_attribute
35
+ private :attribute?
39
36
  end
40
37
  end
41
38
  end