activerecord 5.1.7 → 5.2.4.3

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 (261) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +556 -685
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -5
  5. data/examples/performance.rb +2 -0
  6. data/examples/simple.rb +2 -0
  7. data/lib/active_record.rb +11 -4
  8. data/lib/active_record/aggregations.rb +6 -5
  9. data/lib/active_record/association_relation.rb +7 -5
  10. data/lib/active_record/associations.rb +40 -63
  11. data/lib/active_record/associations/alias_tracker.rb +19 -27
  12. data/lib/active_record/associations/association.rb +41 -37
  13. data/lib/active_record/associations/association_scope.rb +38 -50
  14. data/lib/active_record/associations/belongs_to_association.rb +27 -8
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  16. data/lib/active_record/associations/builder/association.rb +4 -7
  17. data/lib/active_record/associations/builder/belongs_to.rb +12 -4
  18. data/lib/active_record/associations/builder/collection_association.rb +3 -3
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  20. data/lib/active_record/associations/builder/has_many.rb +2 -0
  21. data/lib/active_record/associations/builder/has_one.rb +2 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  23. data/lib/active_record/associations/collection_association.rb +59 -47
  24. data/lib/active_record/associations/collection_proxy.rb +20 -49
  25. data/lib/active_record/associations/foreign_association.rb +2 -0
  26. data/lib/active_record/associations/has_many_association.rb +12 -1
  27. data/lib/active_record/associations/has_many_through_association.rb +36 -30
  28. data/lib/active_record/associations/has_one_association.rb +12 -1
  29. data/lib/active_record/associations/has_one_through_association.rb +13 -8
  30. data/lib/active_record/associations/join_dependency.rb +48 -93
  31. data/lib/active_record/associations/join_dependency/join_association.rb +39 -63
  32. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  33. data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
  34. data/lib/active_record/associations/preloader.rb +18 -38
  35. data/lib/active_record/associations/preloader/association.rb +45 -61
  36. data/lib/active_record/associations/preloader/through_association.rb +71 -79
  37. data/lib/active_record/associations/singular_association.rb +14 -16
  38. data/lib/active_record/associations/through_association.rb +26 -11
  39. data/lib/active_record/attribute_assignment.rb +2 -5
  40. data/lib/active_record/attribute_decorators.rb +3 -2
  41. data/lib/active_record/attribute_methods.rb +65 -24
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  43. data/lib/active_record/attribute_methods/dirty.rb +30 -214
  44. data/lib/active_record/attribute_methods/primary_key.rb +7 -6
  45. data/lib/active_record/attribute_methods/query.rb +2 -0
  46. data/lib/active_record/attribute_methods/read.rb +9 -3
  47. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  49. data/lib/active_record/attribute_methods/write.rb +21 -9
  50. data/lib/active_record/attributes.rb +6 -5
  51. data/lib/active_record/autosave_association.rb +35 -19
  52. data/lib/active_record/base.rb +2 -0
  53. data/lib/active_record/callbacks.rb +8 -6
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +2 -0
  56. data/lib/active_record/collection_cache_key.rb +12 -8
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +139 -41
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +174 -33
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +15 -5
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -31
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +64 -6
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +152 -81
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +84 -97
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
  70. data/lib/active_record/connection_adapters/column.rb +3 -1
  71. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
  73. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -2
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  101. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +233 -111
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -73
  118. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +22 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +81 -94
  127. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  128. data/lib/active_record/connection_handling.rb +4 -2
  129. data/lib/active_record/core.rb +41 -61
  130. data/lib/active_record/counter_cache.rb +10 -3
  131. data/lib/active_record/define_callbacks.rb +5 -3
  132. data/lib/active_record/dynamic_matchers.rb +9 -9
  133. data/lib/active_record/enum.rb +18 -13
  134. data/lib/active_record/errors.rb +42 -3
  135. data/lib/active_record/explain.rb +3 -1
  136. data/lib/active_record/explain_registry.rb +2 -0
  137. data/lib/active_record/explain_subscriber.rb +2 -0
  138. data/lib/active_record/fixture_set/file.rb +2 -0
  139. data/lib/active_record/fixtures.rb +67 -60
  140. data/lib/active_record/gem_version.rb +5 -3
  141. data/lib/active_record/inheritance.rb +49 -19
  142. data/lib/active_record/integration.rb +58 -19
  143. data/lib/active_record/internal_metadata.rb +2 -0
  144. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  145. data/lib/active_record/locking/optimistic.rb +14 -17
  146. data/lib/active_record/locking/pessimistic.rb +9 -6
  147. data/lib/active_record/log_subscriber.rb +43 -0
  148. data/lib/active_record/migration.rb +189 -139
  149. data/lib/active_record/migration/command_recorder.rb +11 -9
  150. data/lib/active_record/migration/compatibility.rb +47 -9
  151. data/lib/active_record/migration/join_table.rb +2 -0
  152. data/lib/active_record/model_schema.rb +16 -21
  153. data/lib/active_record/nested_attributes.rb +18 -6
  154. data/lib/active_record/no_touching.rb +3 -1
  155. data/lib/active_record/null_relation.rb +2 -0
  156. data/lib/active_record/persistence.rb +167 -16
  157. data/lib/active_record/query_cache.rb +6 -8
  158. data/lib/active_record/querying.rb +4 -2
  159. data/lib/active_record/railtie.rb +62 -6
  160. data/lib/active_record/railties/console_sandbox.rb +2 -0
  161. data/lib/active_record/railties/controller_runtime.rb +2 -0
  162. data/lib/active_record/railties/databases.rake +46 -36
  163. data/lib/active_record/readonly_attributes.rb +3 -2
  164. data/lib/active_record/reflection.rb +108 -194
  165. data/lib/active_record/relation.rb +120 -214
  166. data/lib/active_record/relation/batches.rb +20 -5
  167. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  168. data/lib/active_record/relation/calculations.rb +45 -19
  169. data/lib/active_record/relation/delegation.rb +45 -27
  170. data/lib/active_record/relation/finder_methods.rb +75 -76
  171. data/lib/active_record/relation/from_clause.rb +2 -8
  172. data/lib/active_record/relation/merger.rb +53 -23
  173. data/lib/active_record/relation/predicate_builder.rb +60 -79
  174. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  175. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  176. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  177. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  178. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  179. data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
  180. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  181. data/lib/active_record/relation/query_attribute.rb +28 -2
  182. data/lib/active_record/relation/query_methods.rb +128 -99
  183. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  184. data/lib/active_record/relation/spawn_methods.rb +4 -2
  185. data/lib/active_record/relation/where_clause.rb +65 -68
  186. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  187. data/lib/active_record/result.rb +2 -0
  188. data/lib/active_record/runtime_registry.rb +2 -0
  189. data/lib/active_record/sanitization.rb +129 -121
  190. data/lib/active_record/schema.rb +4 -2
  191. data/lib/active_record/schema_dumper.rb +36 -26
  192. data/lib/active_record/schema_migration.rb +2 -0
  193. data/lib/active_record/scoping.rb +9 -8
  194. data/lib/active_record/scoping/default.rb +8 -9
  195. data/lib/active_record/scoping/named.rb +23 -7
  196. data/lib/active_record/secure_token.rb +2 -0
  197. data/lib/active_record/serialization.rb +2 -0
  198. data/lib/active_record/statement_cache.rb +23 -13
  199. data/lib/active_record/store.rb +3 -1
  200. data/lib/active_record/suppressor.rb +2 -0
  201. data/lib/active_record/table_metadata.rb +12 -3
  202. data/lib/active_record/tasks/database_tasks.rb +25 -14
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  206. data/lib/active_record/timestamp.rb +6 -6
  207. data/lib/active_record/touch_later.rb +2 -0
  208. data/lib/active_record/transactions.rb +33 -28
  209. data/lib/active_record/translation.rb +2 -0
  210. data/lib/active_record/type.rb +4 -1
  211. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  212. data/lib/active_record/type/date.rb +2 -0
  213. data/lib/active_record/type/date_time.rb +2 -0
  214. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  215. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  216. data/lib/active_record/type/internal/timezone.rb +2 -0
  217. data/lib/active_record/type/json.rb +30 -0
  218. data/lib/active_record/type/serialized.rb +2 -0
  219. data/lib/active_record/type/text.rb +2 -0
  220. data/lib/active_record/type/time.rb +2 -0
  221. data/lib/active_record/type/type_map.rb +2 -0
  222. data/lib/active_record/type/unsigned_integer.rb +2 -0
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/type_caster/connection.rb +2 -0
  225. data/lib/active_record/type_caster/map.rb +3 -1
  226. data/lib/active_record/validations.rb +2 -0
  227. data/lib/active_record/validations/absence.rb +2 -0
  228. data/lib/active_record/validations/associated.rb +2 -0
  229. data/lib/active_record/validations/length.rb +2 -0
  230. data/lib/active_record/validations/presence.rb +2 -0
  231. data/lib/active_record/validations/uniqueness.rb +35 -5
  232. data/lib/active_record/version.rb +2 -0
  233. data/lib/rails/generators/active_record.rb +3 -1
  234. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  235. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration.rb +2 -0
  237. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  238. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  239. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  241. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  242. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  243. metadata +23 -36
  244. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  245. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  246. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  248. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  249. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  250. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  253. data/lib/active_record/attribute_mutation_tracker.rb +0 -122
  254. data/lib/active_record/attribute_set.rb +0 -113
  255. data/lib/active_record/attribute_set/builder.rb +0 -126
  256. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  257. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  258. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  259. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  260. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  261. 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
@@ -55,7 +57,7 @@ module ActiveRecord
55
57
  unscoped.where(primary_key => object.id).update_all(updates)
56
58
  end
57
59
 
58
- return true
60
+ true
59
61
  end
60
62
 
61
63
  # A generic "counter updater" implementation, intended primarily to be
@@ -114,7 +116,13 @@ module ActiveRecord
114
116
  updates << sanitize_sql_for_assignment(touch_updates) unless touch_updates.empty?
115
117
  end
116
118
 
117
- unscoped.where(primary_key => id).update_all updates.join(", ")
119
+ if id.is_a?(Relation) && self == id.klass
120
+ relation = id
121
+ else
122
+ relation = unscoped.where!(primary_key => id)
123
+ end
124
+
125
+ relation.update_all updates.join(", ")
118
126
  end
119
127
 
120
128
  # Increment a numeric field by one, via a direct SQL update.
@@ -178,7 +186,6 @@ module ActiveRecord
178
186
  each_counter_cached_associations do |association|
179
187
  if send(association.reflection.name)
180
188
  association.increment_counters
181
- @_after_create_counter_called = true
182
189
  end
183
190
  end
184
191
 
@@ -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,24 @@ 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
204
+ enum_values.freeze
202
205
  end
203
206
  end
204
207
 
@@ -219,6 +222,8 @@ module ActiveRecord
219
222
  def detect_enum_conflict!(enum_name, method_name, klass_method = false)
220
223
  if klass_method && dangerous_class_method?(method_name)
221
224
  raise_conflict_error(enum_name, method_name, type: "class")
225
+ elsif klass_method && method_defined_within?(method_name, Relation)
226
+ raise_conflict_error(enum_name, method_name, type: "class", source: Relation.name)
222
227
  elsif !klass_method && dangerous_attribute_method?(method_name)
223
228
  raise_conflict_error(enum_name, method_name)
224
229
  elsif !klass_method && method_defined_within?(method_name, _enum_methods_module, Module)
@@ -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
 
@@ -173,7 +175,7 @@ module ActiveRecord
173
175
  class NoDatabaseError < StatementInvalid
174
176
  end
175
177
 
176
- # Raised when Postgres returns 'cached plan must not change result type' and
178
+ # Raised when PostgreSQL returns 'cached plan must not change result type' and
177
179
  # we cannot retry gracefully (e.g. inside a transaction)
178
180
  class PreparedStatementCacheExpired < StatementInvalid
179
181
  end
@@ -319,7 +321,7 @@ module ActiveRecord
319
321
  #
320
322
  # See the following:
321
323
  #
322
- # * http://www.postgresql.org/docs/current/static/transaction-iso.html
324
+ # * https://www.postgresql.org/docs/current/static/transaction-iso.html
323
325
  # * https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_lock_deadlock
324
326
  class TransactionRollbackError < StatementInvalid
325
327
  end
@@ -338,4 +340,41 @@ module ActiveRecord
338
340
  # +reverse_order+ to automatically reverse.
339
341
  class IrreversibleOrderError < ActiveRecordError
340
342
  end
343
+
344
+ # LockWaitTimeout will be raised when lock wait timeout exceeded.
345
+ class LockWaitTimeout < StatementInvalid
346
+ end
347
+
348
+ # StatementTimeout will be raised when statement timeout exceeded.
349
+ class StatementTimeout < StatementInvalid
350
+ end
351
+
352
+ # QueryCanceled will be raised when canceling statement due to user request.
353
+ class QueryCanceled < StatementInvalid
354
+ end
355
+
356
+ # UnknownAttributeReference is raised when an unknown and potentially unsafe
357
+ # value is passed to a query method when allow_unsafe_raw_sql is set to
358
+ # :disabled. For example, passing a non column name value to a relation's
359
+ # #order method might cause this exception.
360
+ #
361
+ # When working around this exception, caution should be taken to avoid SQL
362
+ # injection vulnerabilities when passing user-provided values to query
363
+ # methods. Known-safe values can be passed to query methods by wrapping them
364
+ # in Arel.sql.
365
+ #
366
+ # For example, with allow_unsafe_raw_sql set to :disabled, the following
367
+ # code would raise this exception:
368
+ #
369
+ # Post.order("length(title)").first
370
+ #
371
+ # The desired result can be accomplished by wrapping the known-safe string
372
+ # in Arel.sql:
373
+ #
374
+ # Post.order(Arel.sql("length(title)")).first
375
+ #
376
+ # Again, such a workaround should *not* be used when passing user-provided
377
+ # values, such as request parameters or model attributes to query methods.
378
+ class UnknownAttributeReference < ActiveRecordError
379
+ end
341
380
  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)))
@@ -148,13 +169,13 @@ module ActiveRecord
148
169
  # self.use_transactional_tests = true
149
170
  #
150
171
  # test "godzilla" do
151
- # assert !Foo.all.empty?
172
+ # assert_not_empty Foo.all
152
173
  # Foo.destroy_all
153
- # assert Foo.all.empty?
174
+ # assert_empty Foo.all
154
175
  # end
155
176
  #
156
177
  # test "godzilla aftermath" do
157
- # assert !Foo.all.empty?
178
+ # assert_not_empty Foo.all
158
179
  # end
159
180
  # end
160
181
  #
@@ -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)
@@ -520,49 +540,38 @@ module ActiveRecord
520
540
  }
521
541
 
522
542
  unless files_to_read.empty?
523
- connection.disable_referential_integrity do
524
- fixtures_map = {}
525
-
526
- fixture_sets = files_to_read.map do |fs_name|
527
- klass = class_names[fs_name]
528
- conn = klass ? klass.connection : connection
529
- fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new
530
- conn,
531
- fs_name,
532
- klass,
533
- ::File.join(fixtures_directory, fs_name))
534
- end
535
-
536
- update_all_loaded_fixtures fixtures_map
537
-
538
- connection.transaction(requires_new: true) do
539
- deleted_tables = Hash.new { |h, k| h[k] = Set.new }
540
- fixture_sets.each do |fs|
541
- conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection
542
- table_rows = fs.table_rows
543
+ fixtures_map = {}
544
+
545
+ fixture_sets = files_to_read.map do |fs_name|
546
+ klass = class_names[fs_name]
547
+ conn = klass ? klass.connection : connection
548
+ fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new
549
+ conn,
550
+ fs_name,
551
+ klass,
552
+ ::File.join(fixtures_directory, fs_name))
553
+ end
543
554
 
544
- table_rows.each_key do |table|
545
- unless deleted_tables[conn].include? table
546
- conn.delete "DELETE FROM #{conn.quote_table_name(table)}", "Fixture Delete"
547
- end
548
- deleted_tables[conn] << table
549
- end
555
+ update_all_loaded_fixtures fixtures_map
556
+ fixture_sets_by_connection = fixture_sets.group_by { |fs| fs.model_class ? fs.model_class.connection : connection }
550
557
 
551
- table_rows.each do |fixture_set_name, rows|
552
- rows.each do |row|
553
- conn.insert_fixture(row, fixture_set_name)
554
- end
555
- end
558
+ fixture_sets_by_connection.each do |conn, set|
559
+ table_rows_for_connection = Hash.new { |h, k| h[k] = [] }
556
560
 
557
- # Cap primary key sequences to max(pk).
558
- if conn.respond_to?(:reset_pk_sequence!)
559
- conn.reset_pk_sequence!(fs.table_name)
560
- end
561
+ set.each do |fs|
562
+ fs.table_rows.each do |table, rows|
563
+ table_rows_for_connection[table].unshift(*rows)
561
564
  end
562
565
  end
566
+ conn.insert_fixtures_set(table_rows_for_connection, table_rows_for_connection.keys)
563
567
 
564
- cache_fixtures(connection, fixtures_map)
568
+ # Cap primary key sequences to max(pk).
569
+ if conn.respond_to?(:reset_pk_sequence!)
570
+ set.each { |fs| conn.reset_pk_sequence!(fs.table_name) }
571
+ end
565
572
  end
573
+
574
+ cache_fixtures(connection, fixtures_map)
566
575
  end
567
576
  cached_fixtures(connection, fixture_set_names)
568
577
  end
@@ -859,20 +868,12 @@ module ActiveRecord
859
868
 
860
869
  included do
861
870
  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
871
+ class_attribute :fixture_table_names, default: []
872
+ class_attribute :fixture_class_names, default: {}
873
+ class_attribute :use_transactional_tests, default: true
874
+ class_attribute :use_instantiated_fixtures, default: false # true, false, or :no_instances
875
+ class_attribute :pre_loaded_fixtures, default: false
876
+ class_attribute :config, default: ActiveRecord::Base
876
877
  end
877
878
 
878
879
  module ClassMethods
@@ -909,6 +910,8 @@ module ActiveRecord
909
910
 
910
911
  define_method(accessor_name) do |*fixture_names|
911
912
  force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
913
+ return_single_record = fixture_names.size == 1
914
+ fixture_names = @loaded_fixtures[fs_name].fixtures.keys if fixture_names.empty?
912
915
 
913
916
  @fixture_cache[fs_name] ||= {}
914
917
 
@@ -923,7 +926,7 @@ module ActiveRecord
923
926
  end
924
927
  end
925
928
 
926
- instances.size == 1 ? instances.first : instances
929
+ return_single_record ? instances.first : instances
927
930
  end
928
931
  private accessor_name
929
932
  end
@@ -1053,6 +1056,10 @@ class ActiveRecord::FixtureSet::RenderContext # :nodoc:
1053
1056
  def get_binding
1054
1057
  binding()
1055
1058
  end
1059
+
1060
+ def binary(path)
1061
+ %(!!binary "#{Base64.strict_encode64(File.read(path))}")
1062
+ end
1056
1063
  end
1057
1064
  end
1058
1065
  end