activerecord 5.1.7 → 5.2.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 (259) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +221 -900
  3. data/README.rdoc +3 -3
  4. data/examples/performance.rb +2 -0
  5. data/examples/simple.rb +2 -0
  6. data/lib/active_record.rb +10 -3
  7. data/lib/active_record/aggregations.rb +2 -0
  8. data/lib/active_record/association_relation.rb +2 -0
  9. data/lib/active_record/associations.rb +13 -42
  10. data/lib/active_record/associations/alias_tracker.rb +17 -17
  11. data/lib/active_record/associations/association.rb +11 -22
  12. data/lib/active_record/associations/association_scope.rb +32 -44
  13. data/lib/active_record/associations/belongs_to_association.rb +6 -4
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -1
  15. data/lib/active_record/associations/builder/association.rb +2 -5
  16. data/lib/active_record/associations/builder/belongs_to.rb +7 -12
  17. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  19. data/lib/active_record/associations/builder/has_many.rb +2 -0
  20. data/lib/active_record/associations/builder/has_one.rb +2 -0
  21. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  22. data/lib/active_record/associations/collection_association.rb +41 -33
  23. data/lib/active_record/associations/collection_proxy.rb +11 -14
  24. data/lib/active_record/associations/foreign_association.rb +2 -0
  25. data/lib/active_record/associations/has_many_association.rb +4 -2
  26. data/lib/active_record/associations/has_many_through_association.rb +4 -2
  27. data/lib/active_record/associations/has_one_association.rb +3 -1
  28. data/lib/active_record/associations/has_one_through_association.rb +3 -1
  29. data/lib/active_record/associations/join_dependency.rb +22 -40
  30. data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
  31. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  32. data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
  33. data/lib/active_record/associations/preloader.rb +17 -37
  34. data/lib/active_record/associations/preloader/association.rb +42 -58
  35. data/lib/active_record/associations/preloader/through_association.rb +71 -79
  36. data/lib/active_record/associations/singular_association.rb +14 -10
  37. data/lib/active_record/associations/through_association.rb +3 -1
  38. data/lib/active_record/attribute_assignment.rb +2 -0
  39. data/lib/active_record/attribute_decorators.rb +3 -2
  40. data/lib/active_record/attribute_methods.rb +47 -7
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  42. data/lib/active_record/attribute_methods/dirty.rb +25 -214
  43. data/lib/active_record/attribute_methods/primary_key.rb +7 -6
  44. data/lib/active_record/attribute_methods/query.rb +2 -0
  45. data/lib/active_record/attribute_methods/read.rb +8 -2
  46. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  48. data/lib/active_record/attribute_methods/write.rb +21 -9
  49. data/lib/active_record/attributes.rb +7 -6
  50. data/lib/active_record/autosave_association.rb +5 -11
  51. data/lib/active_record/base.rb +2 -0
  52. data/lib/active_record/callbacks.rb +6 -8
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +2 -0
  55. data/lib/active_record/collection_cache_key.rb +10 -5
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +120 -28
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -33
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +13 -5
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +40 -2
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +103 -63
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -90
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +75 -138
  69. data/lib/active_record/connection_adapters/column.rb +3 -1
  70. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +3 -1
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -6
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +91 -1
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +3 -5
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -0
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +11 -7
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +79 -65
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +47 -82
  116. data/lib/active_record/connection_adapters/schema_cache.rb +2 -0
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  118. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +19 -2
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  122. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  123. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
  124. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -89
  125. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  126. data/lib/active_record/connection_handling.rb +4 -2
  127. data/lib/active_record/core.rb +27 -57
  128. data/lib/active_record/counter_cache.rb +15 -12
  129. data/lib/active_record/define_callbacks.rb +5 -3
  130. data/lib/active_record/dynamic_matchers.rb +9 -9
  131. data/lib/active_record/enum.rb +15 -13
  132. data/lib/active_record/errors.rb +54 -21
  133. data/lib/active_record/explain.rb +3 -1
  134. data/lib/active_record/explain_registry.rb +2 -0
  135. data/lib/active_record/explain_subscriber.rb +2 -0
  136. data/lib/active_record/fixture_set/file.rb +2 -0
  137. data/lib/active_record/fixtures.rb +40 -24
  138. data/lib/active_record/gem_version.rb +5 -3
  139. data/lib/active_record/inheritance.rb +6 -5
  140. data/lib/active_record/integration.rb +58 -19
  141. data/lib/active_record/internal_metadata.rb +2 -0
  142. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  143. data/lib/active_record/locking/optimistic.rb +31 -20
  144. data/lib/active_record/locking/pessimistic.rb +10 -7
  145. data/lib/active_record/log_subscriber.rb +2 -0
  146. data/lib/active_record/migration.rb +47 -21
  147. data/lib/active_record/migration/command_recorder.rb +11 -9
  148. data/lib/active_record/migration/compatibility.rb +20 -2
  149. data/lib/active_record/migration/join_table.rb +2 -0
  150. data/lib/active_record/model_schema.rb +29 -38
  151. data/lib/active_record/nested_attributes.rb +18 -6
  152. data/lib/active_record/no_touching.rb +3 -1
  153. data/lib/active_record/null_relation.rb +2 -0
  154. data/lib/active_record/persistence.rb +184 -40
  155. data/lib/active_record/query_cache.rb +17 -12
  156. data/lib/active_record/querying.rb +3 -1
  157. data/lib/active_record/railtie.rb +54 -1
  158. data/lib/active_record/railties/console_sandbox.rb +2 -0
  159. data/lib/active_record/railties/controller_runtime.rb +2 -0
  160. data/lib/active_record/railties/databases.rake +41 -28
  161. data/lib/active_record/readonly_attributes.rb +3 -2
  162. data/lib/active_record/reflection.rb +100 -182
  163. data/lib/active_record/relation.rb +61 -193
  164. data/lib/active_record/relation/batches.rb +20 -5
  165. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  166. data/lib/active_record/relation/calculations.rb +40 -23
  167. data/lib/active_record/relation/delegation.rb +10 -27
  168. data/lib/active_record/relation/finder_methods.rb +53 -49
  169. data/lib/active_record/relation/from_clause.rb +2 -8
  170. data/lib/active_record/relation/merger.rb +22 -19
  171. data/lib/active_record/relation/predicate_builder.rb +42 -79
  172. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  173. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  174. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +54 -0
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  179. data/lib/active_record/relation/query_attribute.rb +9 -2
  180. data/lib/active_record/relation/query_methods.rb +80 -69
  181. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  182. data/lib/active_record/relation/spawn_methods.rb +2 -0
  183. data/lib/active_record/relation/where_clause.rb +50 -67
  184. data/lib/active_record/relation/where_clause_factory.rb +4 -46
  185. data/lib/active_record/result.rb +2 -0
  186. data/lib/active_record/runtime_registry.rb +2 -0
  187. data/lib/active_record/sanitization.rb +15 -9
  188. data/lib/active_record/schema.rb +3 -1
  189. data/lib/active_record/schema_dumper.rb +24 -23
  190. data/lib/active_record/schema_migration.rb +2 -0
  191. data/lib/active_record/scoping.rb +9 -8
  192. data/lib/active_record/scoping/default.rb +6 -7
  193. data/lib/active_record/scoping/named.rb +15 -7
  194. data/lib/active_record/secure_token.rb +2 -0
  195. data/lib/active_record/serialization.rb +2 -0
  196. data/lib/active_record/statement_cache.rb +22 -12
  197. data/lib/active_record/store.rb +2 -0
  198. data/lib/active_record/suppressor.rb +2 -0
  199. data/lib/active_record/table_metadata.rb +3 -1
  200. data/lib/active_record/tasks/database_tasks.rb +23 -12
  201. data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
  202. data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
  203. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  204. data/lib/active_record/timestamp.rb +5 -12
  205. data/lib/active_record/touch_later.rb +2 -0
  206. data/lib/active_record/transactions.rb +9 -7
  207. data/lib/active_record/translation.rb +2 -0
  208. data/lib/active_record/type.rb +4 -1
  209. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  210. data/lib/active_record/type/date.rb +2 -0
  211. data/lib/active_record/type/date_time.rb +2 -0
  212. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  213. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  214. data/lib/active_record/type/internal/timezone.rb +2 -0
  215. data/lib/active_record/type/json.rb +30 -0
  216. data/lib/active_record/type/serialized.rb +2 -4
  217. data/lib/active_record/type/text.rb +2 -0
  218. data/lib/active_record/type/time.rb +2 -0
  219. data/lib/active_record/type/type_map.rb +2 -0
  220. data/lib/active_record/type/unsigned_integer.rb +2 -0
  221. data/lib/active_record/type_caster.rb +2 -0
  222. data/lib/active_record/type_caster/connection.rb +2 -0
  223. data/lib/active_record/type_caster/map.rb +2 -0
  224. data/lib/active_record/validations.rb +2 -0
  225. data/lib/active_record/validations/absence.rb +2 -0
  226. data/lib/active_record/validations/associated.rb +2 -0
  227. data/lib/active_record/validations/length.rb +2 -0
  228. data/lib/active_record/validations/presence.rb +2 -0
  229. data/lib/active_record/validations/uniqueness.rb +36 -6
  230. data/lib/active_record/version.rb +2 -0
  231. data/lib/rails/generators/active_record.rb +3 -1
  232. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  233. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  234. data/lib/rails/generators/active_record/migration.rb +2 -0
  235. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  236. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  237. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  238. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  239. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  241. metadata +25 -38
  242. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  243. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  244. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  245. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  246. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  248. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  249. data/lib/active_record/attribute.rb +0 -240
  250. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  251. data/lib/active_record/attribute_mutation_tracker.rb +0 -122
  252. data/lib/active_record/attribute_set.rb +0 -113
  253. data/lib/active_record/attribute_set/builder.rb +0 -126
  254. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  255. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  256. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  257. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  258. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  259. data/lib/active_record/type/internal/abstract_json.rb +0 -37
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record Counter Cache
3
5
  module CounterCache
@@ -45,17 +47,13 @@ module ActiveRecord
45
47
  reflection = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
46
48
  counter_name = reflection.counter_cache_column
47
49
 
48
- updates = { counter_name => object.send(counter_association).count(:all) }
49
-
50
- if touch
51
- names = touch if touch != true
52
- updates.merge!(touch_attributes_with_time(*names))
53
- end
50
+ updates = { counter_name.to_sym => object.send(counter_association).count(:all) }
51
+ updates.merge!(touch_updates(touch)) if touch
54
52
 
55
53
  unscoped.where(primary_key => object.id).update_all(updates)
56
54
  end
57
55
 
58
- return true
56
+ true
59
57
  end
60
58
 
61
59
  # A generic "counter updater" implementation, intended primarily to be
@@ -70,8 +68,8 @@ module ActiveRecord
70
68
  # * +counters+ - A Hash containing the names of the fields
71
69
  # to update as keys and the amount to update the field by as values.
72
70
  # * <tt>:touch</tt> option - Touch timestamp columns when updating.
73
- # If attribute names are passed, they are updated along with updated_at/on
74
- # attributes.
71
+ # Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
72
+ # touch that column or an array of symbols to touch just those ones.
75
73
  #
76
74
  # ==== Examples
77
75
  #
@@ -109,8 +107,7 @@ module ActiveRecord
109
107
  end
110
108
 
111
109
  if touch
112
- names = touch if touch != true
113
- touch_updates = touch_attributes_with_time(*names)
110
+ touch_updates = touch_updates(touch)
114
111
  updates << sanitize_sql_for_assignment(touch_updates) unless touch_updates.empty?
115
112
  end
116
113
 
@@ -168,6 +165,13 @@ module ActiveRecord
168
165
  def decrement_counter(counter_name, id, touch: nil)
169
166
  update_counters(id, counter_name => -1, touch: touch)
170
167
  end
168
+
169
+ private
170
+ def touch_updates(touch)
171
+ touch = timestamp_attributes_for_update_in_model if touch == true
172
+ touch_time = current_time_from_proper_timezone
173
+ Array(touch).map { |column| [ column, touch_time ] }.to_h
174
+ end
171
175
  end
172
176
 
173
177
  private
@@ -178,7 +182,6 @@ module ActiveRecord
178
182
  each_counter_cached_associations do |association|
179
183
  if send(association.reflection.name)
180
184
  association.increment_counters
181
- @_after_create_counter_called = true
182
185
  end
183
186
  end
184
187
 
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # This module exists because `ActiveRecord::AttributeMethods::Dirty` needs to
3
- # define callbacks, but continue to have its version of `save` be the super
4
- # method of `ActiveRecord::Callbacks`. This will be removed when the removal
4
+ # This module exists because ActiveRecord::AttributeMethods::Dirty needs to
5
+ # define callbacks, but continue to have its version of +save+ be the super
6
+ # method of ActiveRecord::Callbacks. This will be removed when the removal
5
7
  # of deprecated code removes this need.
6
8
  module DefineCallbacks
7
9
  extend ActiveSupport::Concern
@@ -1,16 +1,16 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module ActiveRecord
3
4
  module DynamicMatchers #:nodoc:
4
- def respond_to_missing?(name, include_private = false)
5
- if self == Base
6
- super
7
- else
8
- match = Method.match(self, name)
9
- match && match.valid? || super
10
- end
11
- end
12
-
13
5
  private
6
+ def respond_to_missing?(name, _)
7
+ if self == Base
8
+ super
9
+ else
10
+ match = Method.match(self, name)
11
+ match && match.valid? || super
12
+ end
13
+ end
14
14
 
15
15
  def method_missing(name, *arguments, &block)
16
16
  match = Method.match(self, name)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/deep_dup"
2
4
 
3
5
  module ActiveRecord
@@ -95,8 +97,7 @@ module ActiveRecord
95
97
 
96
98
  module Enum
97
99
  def self.extended(base) # :nodoc:
98
- base.class_attribute(:defined_enums, instance_writer: false)
99
- base.defined_enums = {}
100
+ base.class_attribute(:defined_enums, instance_writer: false, default: {})
100
101
  end
101
102
 
102
103
  def inherited(base) # :nodoc:
@@ -154,11 +155,12 @@ module ActiveRecord
154
155
  definitions.each do |name, values|
155
156
  # statuses = { }
156
157
  enum_values = ActiveSupport::HashWithIndifferentAccess.new
157
- name = name.to_sym
158
+ name = name.to_s
158
159
 
159
160
  # def self.statuses() statuses end
160
- detect_enum_conflict!(name, name.to_s.pluralize, true)
161
- klass.singleton_class.send(:define_method, name.to_s.pluralize) { enum_values }
161
+ detect_enum_conflict!(name, name.pluralize, true)
162
+ singleton_class.send(:define_method, name.pluralize) { enum_values }
163
+ defined_enums[name] = enum_values
162
164
 
163
165
  detect_enum_conflict!(name, name)
164
166
  detect_enum_conflict!(name, "#{name}=")
@@ -170,7 +172,7 @@ module ActiveRecord
170
172
 
171
173
  _enum_methods_module.module_eval do
172
174
  pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
173
- pairs.each do |value, i|
175
+ pairs.each do |label, value|
174
176
  if enum_prefix == true
175
177
  prefix = "#{name}_"
176
178
  elsif enum_prefix
@@ -182,23 +184,23 @@ module ActiveRecord
182
184
  suffix = "_#{enum_suffix}"
183
185
  end
184
186
 
185
- value_method_name = "#{prefix}#{value}#{suffix}"
186
- enum_values[value] = i
187
+ value_method_name = "#{prefix}#{label}#{suffix}"
188
+ enum_values[label] = value
189
+ label = label.to_s
187
190
 
188
- # def active?() status == 0 end
191
+ # def active?() status == "active" end
189
192
  klass.send(:detect_enum_conflict!, name, "#{value_method_name}?")
190
- define_method("#{value_method_name}?") { self[attr] == value.to_s }
193
+ define_method("#{value_method_name}?") { self[attr] == label }
191
194
 
192
- # def active!() update! status: :active end
195
+ # def active!() update!(status: 0) end
193
196
  klass.send(:detect_enum_conflict!, name, "#{value_method_name}!")
194
197
  define_method("#{value_method_name}!") { update!(attr => value) }
195
198
 
196
- # scope :active, -> { where status: 0 }
199
+ # scope :active, -> { where(status: 0) }
197
200
  klass.send(:detect_enum_conflict!, name, value_method_name, true)
198
201
  klass.scope value_method_name, -> { where(attr => value) }
199
202
  end
200
203
  end
201
- defined_enums[name.to_s] = enum_values
202
204
  end
203
205
  end
204
206
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record Errors
3
5
  #
@@ -105,7 +107,7 @@ module ActiveRecord
105
107
  class WrappedDatabaseException < StatementInvalid
106
108
  end
107
109
 
108
- # Raised when a record cannot be inserted because it would violate a uniqueness constraint.
110
+ # Raised when a record cannot be inserted or updated because it would violate a uniqueness constraint.
109
111
  class RecordNotUnique < WrappedDatabaseException
110
112
  end
111
113
 
@@ -115,27 +117,16 @@ module ActiveRecord
115
117
 
116
118
  # Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
117
119
  class MismatchedForeignKey < StatementInvalid
118
- def initialize(
119
- adapter = nil,
120
- message: nil,
121
- sql: nil,
122
- binds: nil,
123
- table: nil,
124
- foreign_key: nil,
125
- target_table: nil,
126
- primary_key: nil,
127
- primary_key_column: nil
128
- )
120
+ def initialize(adapter = nil, message: nil, table: nil, foreign_key: nil, target_table: nil, primary_key: nil)
121
+ @adapter = adapter
129
122
  if table
130
- type = primary_key_column.bigint? ? :bigint : primary_key_column.type
131
- msg = <<-EOM.squish
132
- Column `#{foreign_key}` on table `#{table}` does not match column `#{primary_key}` on `#{target_table}`,
133
- which has type `#{primary_key_column.sql_type}`.
134
- To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
135
- (For example `t.#{type} :#{foreign_key}`).
123
+ msg = <<-EOM.strip_heredoc
124
+ Column `#{foreign_key}` on table `#{table}` has a type of `#{column_type(table, foreign_key)}`.
125
+ This does not match column `#{primary_key}` on `#{target_table}`, which has type `#{column_type(target_table, primary_key)}`.
126
+ To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :integer. (For example `t.integer #{foreign_key}`).
136
127
  EOM
137
128
  else
138
- msg = <<-EOM.squish
129
+ msg = <<-EOM
139
130
  There is a mismatch between the foreign key and primary key column types.
140
131
  Verify that the foreign key column type and the primary key of the associated table match types.
141
132
  EOM
@@ -145,6 +136,11 @@ module ActiveRecord
145
136
  end
146
137
  super(msg)
147
138
  end
139
+
140
+ private
141
+ def column_type(table, column)
142
+ @adapter.columns(table).detect { |c| c.name == column }.sql_type
143
+ end
148
144
  end
149
145
 
150
146
  # Raised when a record cannot be inserted or updated because it would violate a not null constraint.
@@ -173,7 +169,7 @@ module ActiveRecord
173
169
  class NoDatabaseError < StatementInvalid
174
170
  end
175
171
 
176
- # Raised when Postgres returns 'cached plan must not change result type' and
172
+ # Raised when PostgreSQL returns 'cached plan must not change result type' and
177
173
  # we cannot retry gracefully (e.g. inside a transaction)
178
174
  class PreparedStatementCacheExpired < StatementInvalid
179
175
  end
@@ -319,7 +315,7 @@ module ActiveRecord
319
315
  #
320
316
  # See the following:
321
317
  #
322
- # * http://www.postgresql.org/docs/current/static/transaction-iso.html
318
+ # * https://www.postgresql.org/docs/current/static/transaction-iso.html
323
319
  # * https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_lock_deadlock
324
320
  class TransactionRollbackError < StatementInvalid
325
321
  end
@@ -338,4 +334,41 @@ module ActiveRecord
338
334
  # +reverse_order+ to automatically reverse.
339
335
  class IrreversibleOrderError < ActiveRecordError
340
336
  end
337
+
338
+ # LockWaitTimeout will be raised when lock wait timeout exceeded.
339
+ class LockWaitTimeout < StatementInvalid
340
+ end
341
+
342
+ # StatementTimeout will be raised when statement timeout exceeded.
343
+ class StatementTimeout < StatementInvalid
344
+ end
345
+
346
+ # QueryCanceled will be raised when canceling statement due to user request.
347
+ class QueryCanceled < StatementInvalid
348
+ end
349
+
350
+ # UnknownAttributeReference is raised when an unknown and potentially unsafe
351
+ # value is passed to a query method when allow_unsafe_raw_sql is set to
352
+ # :disabled. For example, passing a non column name value to a relation's
353
+ # #order method might cause this exception.
354
+ #
355
+ # When working around this exception, caution should be taken to avoid SQL
356
+ # injection vulnerabilities when passing user-provided values to query
357
+ # methods. Known-safe values can be passed to query methods by wrapping them
358
+ # in Arel.sql.
359
+ #
360
+ # For example, with allow_unsafe_raw_sql set to :disabled, the following
361
+ # code would raise this exception:
362
+ #
363
+ # Post.order("length(title)").first
364
+ #
365
+ # The desired result can be accomplished by wrapping the known-safe string
366
+ # in Arel.sql:
367
+ #
368
+ # Post.order(Arel.sql("length(title)")).first
369
+ #
370
+ # Again, such a workaround should *not* be used when passing user-provided
371
+ # values, such as request parameters or model attributes to query methods.
372
+ class UnknownAttributeReference < ActiveRecordError
373
+ end
341
374
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_record/explain_registry"
2
4
 
3
5
  module ActiveRecord
@@ -16,7 +18,7 @@ module ActiveRecord
16
18
  # Returns a formatted string ready to be logged.
17
19
  def exec_explain(queries) # :nodoc:
18
20
  str = queries.map do |sql, binds|
19
- msg = "EXPLAIN for: #{sql}"
21
+ msg = "EXPLAIN for: #{sql}".dup
20
22
  unless binds.empty?
21
23
  msg << " "
22
24
  msg << binds.map { |attr| render_bind(attr) }.inspect
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/per_thread_registry"
2
4
 
3
5
  module ActiveRecord
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/notifications"
2
4
  require "active_record/explain_registry"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "erb"
2
4
  require "yaml"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "erb"
2
4
  require "yaml"
3
5
  require "zlib"
@@ -70,13 +72,32 @@ module ActiveRecord
70
72
  # test. To ensure consistent data, the environment deletes the fixtures before running the load.
71
73
  #
72
74
  # In addition to being available in the database, the fixture's data may also be accessed by
73
- # using a special dynamic method, which has the same name as the model, and accepts the
74
- # name of the fixture to instantiate:
75
+ # using a special dynamic method, which has the same name as the model.
76
+ #
77
+ # Passing in a fixture name to this dynamic method returns the fixture matching this name:
75
78
  #
76
- # test "find" do
79
+ # test "find one" do
77
80
  # assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
78
81
  # end
79
82
  #
83
+ # Passing in multiple fixture names returns all fixtures matching these names:
84
+ #
85
+ # test "find all by name" do
86
+ # assert_equal 2, web_sites(:rubyonrails, :google).length
87
+ # end
88
+ #
89
+ # Passing in no arguments returns all fixtures:
90
+ #
91
+ # test "find all" do
92
+ # assert_equal 2, web_sites.length
93
+ # end
94
+ #
95
+ # Passing in any fixture name that does not exist will raise <tt>StandardError</tt>:
96
+ #
97
+ # test "find by name that does not exist" do
98
+ # assert_raise(StandardError) { web_sites(:reddit) }
99
+ # end
100
+ #
80
101
  # Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the
81
102
  # following tests:
82
103
  #
@@ -126,7 +147,7 @@ module ActiveRecord
126
147
  # unwanted inter-test dependencies. Methods used by multiple fixtures should be defined in a module
127
148
  # that is included in ActiveRecord::FixtureSet.context_class.
128
149
  #
129
- # - define a helper method in `test_helper.rb`
150
+ # - define a helper method in <tt>test_helper.rb</tt>
130
151
  # module FixtureFileHelpers
131
152
  # def file_sha(path)
132
153
  # Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
@@ -473,8 +494,7 @@ module ActiveRecord
473
494
  end
474
495
  end
475
496
 
476
- cattr_accessor :all_loaded_fixtures
477
- self.all_loaded_fixtures = {}
497
+ cattr_accessor :all_loaded_fixtures, default: {}
478
498
 
479
499
  class ClassCache
480
500
  def initialize(class_names, config)
@@ -549,9 +569,7 @@ module ActiveRecord
549
569
  end
550
570
 
551
571
  table_rows.each do |fixture_set_name, rows|
552
- rows.each do |row|
553
- conn.insert_fixture(row, fixture_set_name)
554
- end
572
+ conn.insert_fixtures(rows, fixture_set_name)
555
573
  end
556
574
 
557
575
  # Cap primary key sequences to max(pk).
@@ -859,20 +877,12 @@ module ActiveRecord
859
877
 
860
878
  included do
861
879
  class_attribute :fixture_path, instance_writer: false
862
- class_attribute :fixture_table_names
863
- class_attribute :fixture_class_names
864
- class_attribute :use_transactional_tests
865
- class_attribute :use_instantiated_fixtures # true, false, or :no_instances
866
- class_attribute :pre_loaded_fixtures
867
- class_attribute :config
868
-
869
- self.fixture_table_names = []
870
- self.use_instantiated_fixtures = false
871
- self.pre_loaded_fixtures = false
872
- self.config = ActiveRecord::Base
873
-
874
- self.fixture_class_names = {}
875
- self.use_transactional_tests = true
880
+ class_attribute :fixture_table_names, default: []
881
+ class_attribute :fixture_class_names, default: {}
882
+ class_attribute :use_transactional_tests, default: true
883
+ class_attribute :use_instantiated_fixtures, default: false # true, false, or :no_instances
884
+ class_attribute :pre_loaded_fixtures, default: false
885
+ class_attribute :config, default: ActiveRecord::Base
876
886
  end
877
887
 
878
888
  module ClassMethods
@@ -909,6 +919,8 @@ module ActiveRecord
909
919
 
910
920
  define_method(accessor_name) do |*fixture_names|
911
921
  force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
922
+ return_single_record = fixture_names.size == 1
923
+ fixture_names = @loaded_fixtures[fs_name].fixtures.keys if fixture_names.empty?
912
924
 
913
925
  @fixture_cache[fs_name] ||= {}
914
926
 
@@ -923,7 +935,7 @@ module ActiveRecord
923
935
  end
924
936
  end
925
937
 
926
- instances.size == 1 ? instances.first : instances
938
+ return_single_record ? instances.first : instances
927
939
  end
928
940
  private accessor_name
929
941
  end
@@ -1053,6 +1065,10 @@ class ActiveRecord::FixtureSet::RenderContext # :nodoc:
1053
1065
  def get_binding
1054
1066
  binding()
1055
1067
  end
1068
+
1069
+ def binary(path)
1070
+ %(!!binary "#{Base64.strict_encode64(File.read(path))}")
1071
+ end
1056
1072
  end
1057
1073
  end
1058
1074
  end