activerecord 3.2.22.5 → 5.2.8

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 (275) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +657 -621
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +41 -46
  5. data/examples/performance.rb +55 -42
  6. data/examples/simple.rb +6 -5
  7. data/lib/active_record/aggregations.rb +264 -236
  8. data/lib/active_record/association_relation.rb +40 -0
  9. data/lib/active_record/associations/alias_tracker.rb +47 -42
  10. data/lib/active_record/associations/association.rb +127 -75
  11. data/lib/active_record/associations/association_scope.rb +126 -92
  12. data/lib/active_record/associations/belongs_to_association.rb +78 -27
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +9 -4
  14. data/lib/active_record/associations/builder/association.rb +117 -32
  15. data/lib/active_record/associations/builder/belongs_to.rb +135 -60
  16. data/lib/active_record/associations/builder/collection_association.rb +61 -54
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +120 -42
  18. data/lib/active_record/associations/builder/has_many.rb +10 -64
  19. data/lib/active_record/associations/builder/has_one.rb +19 -51
  20. data/lib/active_record/associations/builder/singular_association.rb +28 -18
  21. data/lib/active_record/associations/collection_association.rb +226 -293
  22. data/lib/active_record/associations/collection_proxy.rb +1067 -69
  23. data/lib/active_record/associations/foreign_association.rb +13 -0
  24. data/lib/active_record/associations/has_many_association.rb +83 -47
  25. data/lib/active_record/associations/has_many_through_association.rb +98 -65
  26. data/lib/active_record/associations/has_one_association.rb +57 -20
  27. data/lib/active_record/associations/has_one_through_association.rb +18 -9
  28. data/lib/active_record/associations/join_dependency/join_association.rb +48 -126
  29. data/lib/active_record/associations/join_dependency/join_base.rb +11 -12
  30. data/lib/active_record/associations/join_dependency/join_part.rb +35 -42
  31. data/lib/active_record/associations/join_dependency.rb +212 -164
  32. data/lib/active_record/associations/preloader/association.rb +95 -89
  33. data/lib/active_record/associations/preloader/through_association.rb +84 -44
  34. data/lib/active_record/associations/preloader.rb +123 -111
  35. data/lib/active_record/associations/singular_association.rb +33 -24
  36. data/lib/active_record/associations/through_association.rb +60 -26
  37. data/lib/active_record/associations.rb +1759 -1506
  38. data/lib/active_record/attribute_assignment.rb +60 -193
  39. data/lib/active_record/attribute_decorators.rb +90 -0
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +55 -8
  41. data/lib/active_record/attribute_methods/dirty.rb +113 -74
  42. data/lib/active_record/attribute_methods/primary_key.rb +106 -77
  43. data/lib/active_record/attribute_methods/query.rb +8 -5
  44. data/lib/active_record/attribute_methods/read.rb +63 -114
  45. data/lib/active_record/attribute_methods/serialization.rb +60 -90
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +69 -43
  47. data/lib/active_record/attribute_methods/write.rb +43 -45
  48. data/lib/active_record/attribute_methods.rb +366 -149
  49. data/lib/active_record/attributes.rb +266 -0
  50. data/lib/active_record/autosave_association.rb +312 -225
  51. data/lib/active_record/base.rb +114 -505
  52. data/lib/active_record/callbacks.rb +145 -67
  53. data/lib/active_record/coders/json.rb +15 -0
  54. data/lib/active_record/coders/yaml_column.rb +32 -23
  55. data/lib/active_record/collection_cache_key.rb +53 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +883 -284
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +16 -2
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +350 -200
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -27
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +150 -65
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +146 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +477 -284
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +95 -0
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1100 -310
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +283 -0
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +450 -118
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +657 -446
  69. data/lib/active_record/connection_adapters/column.rb +50 -255
  70. data/lib/active_record/connection_adapters/connection_specification.rb +287 -0
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +33 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +140 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +73 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +87 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +80 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +148 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +35 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -210
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -0
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +163 -0
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +92 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +56 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +50 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +23 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +41 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +111 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +34 -0
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +168 -0
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +206 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +774 -0
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +620 -1080
  117. data/lib/active_record/connection_adapters/schema_cache.rb +85 -36
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +34 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +67 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +106 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +545 -27
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +145 -0
  128. data/lib/active_record/core.rb +559 -0
  129. data/lib/active_record/counter_cache.rb +200 -105
  130. data/lib/active_record/define_callbacks.rb +22 -0
  131. data/lib/active_record/dynamic_matchers.rb +107 -69
  132. data/lib/active_record/enum.rb +244 -0
  133. data/lib/active_record/errors.rb +245 -60
  134. data/lib/active_record/explain.rb +35 -71
  135. data/lib/active_record/explain_registry.rb +32 -0
  136. data/lib/active_record/explain_subscriber.rb +18 -9
  137. data/lib/active_record/fixture_set/file.rb +82 -0
  138. data/lib/active_record/fixtures.rb +418 -275
  139. data/lib/active_record/gem_version.rb +17 -0
  140. data/lib/active_record/inheritance.rb +209 -100
  141. data/lib/active_record/integration.rb +116 -21
  142. data/lib/active_record/internal_metadata.rb +45 -0
  143. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  144. data/lib/active_record/locale/en.yml +9 -1
  145. data/lib/active_record/locking/optimistic.rb +107 -94
  146. data/lib/active_record/locking/pessimistic.rb +20 -8
  147. data/lib/active_record/log_subscriber.rb +99 -34
  148. data/lib/active_record/migration/command_recorder.rb +199 -64
  149. data/lib/active_record/migration/compatibility.rb +217 -0
  150. data/lib/active_record/migration/join_table.rb +17 -0
  151. data/lib/active_record/migration.rb +893 -296
  152. data/lib/active_record/model_schema.rb +328 -175
  153. data/lib/active_record/nested_attributes.rb +338 -242
  154. data/lib/active_record/no_touching.rb +58 -0
  155. data/lib/active_record/null_relation.rb +68 -0
  156. data/lib/active_record/persistence.rb +557 -170
  157. data/lib/active_record/query_cache.rb +14 -43
  158. data/lib/active_record/querying.rb +36 -24
  159. data/lib/active_record/railtie.rb +147 -52
  160. data/lib/active_record/railties/console_sandbox.rb +5 -4
  161. data/lib/active_record/railties/controller_runtime.rb +13 -6
  162. data/lib/active_record/railties/databases.rake +206 -488
  163. data/lib/active_record/readonly_attributes.rb +4 -6
  164. data/lib/active_record/reflection.rb +734 -228
  165. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  166. data/lib/active_record/relation/batches.rb +249 -52
  167. data/lib/active_record/relation/calculations.rb +330 -284
  168. data/lib/active_record/relation/delegation.rb +135 -37
  169. data/lib/active_record/relation/finder_methods.rb +450 -287
  170. data/lib/active_record/relation/from_clause.rb +26 -0
  171. data/lib/active_record/relation/merger.rb +193 -0
  172. data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
  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 +19 -0
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +20 -0
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +42 -0
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +19 -0
  179. data/lib/active_record/relation/predicate_builder.rb +132 -43
  180. data/lib/active_record/relation/query_attribute.rb +45 -0
  181. data/lib/active_record/relation/query_methods.rb +1037 -221
  182. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  183. data/lib/active_record/relation/spawn_methods.rb +48 -151
  184. data/lib/active_record/relation/where_clause.rb +186 -0
  185. data/lib/active_record/relation/where_clause_factory.rb +34 -0
  186. data/lib/active_record/relation.rb +451 -359
  187. data/lib/active_record/result.rb +129 -20
  188. data/lib/active_record/runtime_registry.rb +24 -0
  189. data/lib/active_record/sanitization.rb +164 -136
  190. data/lib/active_record/schema.rb +31 -19
  191. data/lib/active_record/schema_dumper.rb +154 -107
  192. data/lib/active_record/schema_migration.rb +56 -0
  193. data/lib/active_record/scoping/default.rb +108 -98
  194. data/lib/active_record/scoping/named.rb +125 -112
  195. data/lib/active_record/scoping.rb +77 -123
  196. data/lib/active_record/secure_token.rb +40 -0
  197. data/lib/active_record/serialization.rb +10 -6
  198. data/lib/active_record/statement_cache.rb +121 -0
  199. data/lib/active_record/store.rb +175 -16
  200. data/lib/active_record/suppressor.rb +61 -0
  201. data/lib/active_record/table_metadata.rb +82 -0
  202. data/lib/active_record/tasks/database_tasks.rb +337 -0
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +143 -0
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +83 -0
  206. data/lib/active_record/timestamp.rb +80 -41
  207. data/lib/active_record/touch_later.rb +64 -0
  208. data/lib/active_record/transactions.rb +240 -119
  209. data/lib/active_record/translation.rb +2 -0
  210. data/lib/active_record/type/adapter_specific_registry.rb +136 -0
  211. data/lib/active_record/type/date.rb +9 -0
  212. data/lib/active_record/type/date_time.rb +9 -0
  213. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  214. data/lib/active_record/type/hash_lookup_type_map.rb +25 -0
  215. data/lib/active_record/type/internal/timezone.rb +17 -0
  216. data/lib/active_record/type/json.rb +30 -0
  217. data/lib/active_record/type/serialized.rb +71 -0
  218. data/lib/active_record/type/text.rb +11 -0
  219. data/lib/active_record/type/time.rb +21 -0
  220. data/lib/active_record/type/type_map.rb +62 -0
  221. data/lib/active_record/type/unsigned_integer.rb +17 -0
  222. data/lib/active_record/type.rb +79 -0
  223. data/lib/active_record/type_caster/connection.rb +33 -0
  224. data/lib/active_record/type_caster/map.rb +23 -0
  225. data/lib/active_record/type_caster.rb +9 -0
  226. data/lib/active_record/validations/absence.rb +25 -0
  227. data/lib/active_record/validations/associated.rb +35 -18
  228. data/lib/active_record/validations/length.rb +26 -0
  229. data/lib/active_record/validations/presence.rb +68 -0
  230. data/lib/active_record/validations/uniqueness.rb +133 -75
  231. data/lib/active_record/validations.rb +53 -43
  232. data/lib/active_record/version.rb +7 -7
  233. data/lib/active_record.rb +89 -57
  234. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  235. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  236. data/lib/rails/generators/active_record/migration/migration_generator.rb +61 -8
  237. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  238. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +46 -0
  239. data/lib/rails/generators/active_record/migration.rb +28 -8
  240. data/lib/rails/generators/active_record/model/model_generator.rb +23 -22
  241. data/lib/rails/generators/active_record/model/templates/model.rb.tt +13 -0
  242. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +1 -1
  243. data/lib/rails/generators/active_record.rb +10 -16
  244. metadata +141 -62
  245. data/examples/associations.png +0 -0
  246. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  247. data/lib/active_record/associations/join_helper.rb +0 -55
  248. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  249. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  250. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  251. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  252. data/lib/active_record/associations/preloader/has_many_through.rb +0 -15
  253. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  254. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  255. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  256. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  257. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  258. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -441
  259. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  260. data/lib/active_record/dynamic_finder_match.rb +0 -68
  261. data/lib/active_record/dynamic_scope_match.rb +0 -23
  262. data/lib/active_record/fixtures/file.rb +0 -65
  263. data/lib/active_record/identity_map.rb +0 -162
  264. data/lib/active_record/observer.rb +0 -121
  265. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  266. data/lib/active_record/serializers/xml_serializer.rb +0 -203
  267. data/lib/active_record/session_store.rb +0 -360
  268. data/lib/active_record/test_case.rb +0 -73
  269. data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -34
  270. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
  271. data/lib/rails/generators/active_record/model/templates/model.rb +0 -12
  272. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  273. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  274. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  275. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,12 +1,13 @@
1
- require 'active_support/core_ext/object/blank'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
4
  # = Active Record Query Cache
5
5
  class QueryCache
6
6
  module ClassMethods
7
7
  # Enable the query cache within the block if Active Record is configured.
8
+ # If it's not, it will execute the given block.
8
9
  def cache(&block)
9
- if ActiveRecord::Base.connected?
10
+ if connected? || !configurations.empty?
10
11
  connection.cache(&block)
11
12
  else
12
13
  yield
@@ -14,8 +15,9 @@ module ActiveRecord
14
15
  end
15
16
 
16
17
  # Disable the query cache within the block if Active Record is configured.
18
+ # If it's not, it will execute the given block.
17
19
  def uncached(&block)
18
- if ActiveRecord::Base.connected?
20
+ if connected? || !configurations.empty?
19
21
  connection.uncached(&block)
20
22
  else
21
23
  yield
@@ -23,52 +25,21 @@ module ActiveRecord
23
25
  end
24
26
  end
25
27
 
26
- def initialize(app)
27
- @app = app
28
+ def self.run
29
+ ActiveRecord::Base.connection_handler.connection_pool_list.
30
+ reject { |p| p.query_cache_enabled }.each { |p| p.enable_query_cache! }
28
31
  end
29
32
 
30
- class BodyProxy # :nodoc:
31
- def initialize(original_cache_value, target, connection_id)
32
- @original_cache_value = original_cache_value
33
- @target = target
34
- @connection_id = connection_id
35
- end
36
-
37
- def method_missing(method_sym, *arguments, &block)
38
- @target.send(method_sym, *arguments, &block)
39
- end
40
-
41
- def respond_to?(method_sym, include_private = false)
42
- super || @target.respond_to?(method_sym)
43
- end
33
+ def self.complete(pools)
34
+ pools.each { |pool| pool.disable_query_cache! }
44
35
 
45
- def each(&block)
46
- @target.each(&block)
47
- end
48
-
49
- def close
50
- @target.close if @target.respond_to?(:close)
51
- ensure
52
- ActiveRecord::Base.connection_id = @connection_id
53
- ActiveRecord::Base.connection.clear_query_cache
54
- unless @original_cache_value
55
- ActiveRecord::Base.connection.disable_query_cache!
56
- end
36
+ ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
37
+ pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
57
38
  end
58
39
  end
59
40
 
60
- def call(env)
61
- old = ActiveRecord::Base.connection.query_cache_enabled
62
- ActiveRecord::Base.connection.enable_query_cache!
63
-
64
- status, headers, body = @app.call(env)
65
- [status, headers, BodyProxy.new(old, body, ActiveRecord::Base.connection_id)]
66
- rescue Exception => e
67
- ActiveRecord::Base.connection.clear_query_cache
68
- unless old
69
- ActiveRecord::Base.connection.disable_query_cache!
70
- end
71
- raise e
41
+ def self.install_executor_hooks(executor = ActiveSupport::Executor)
42
+ executor.register_hook(self)
72
43
  end
73
44
  end
74
45
  end
@@ -1,20 +1,24 @@
1
- require 'active_support/core_ext/module/delegation'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
4
  module Querying
5
- delegate :find, :first, :first!, :last, :last!, :all, :exists?, :any?, :many?, :to => :scoped
6
- delegate :first_or_create, :first_or_create!, :first_or_initialize, :to => :scoped
7
- delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, :to => :scoped
8
- delegate :find_each, :find_in_batches, :to => :scoped
9
- delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins,
10
- :where, :preload, :eager_load, :includes, :from, :lock, :readonly,
11
- :having, :create_with, :uniq, :to => :scoped
12
- delegate :count, :average, :minimum, :maximum, :sum, :calculate, :pluck, :to => :scoped
5
+ delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :none?, :one?, to: :all
6
+ delegate :second, :second!, :third, :third!, :fourth, :fourth!, :fifth, :fifth!, :forty_two, :forty_two!, :third_to_last, :third_to_last!, :second_to_last, :second_to_last!, to: :all
7
+ delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
8
+ delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
9
+ delegate :find_by, :find_by!, to: :all
10
+ delegate :destroy_all, :delete_all, :update_all, to: :all
11
+ delegate :find_each, :find_in_batches, :in_batches, to: :all
12
+ delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
13
+ :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
14
+ :having, :create_with, :distinct, :references, :none, :unscope, :merge, to: :all
15
+ delegate :count, :average, :minimum, :maximum, :sum, :calculate, to: :all
16
+ delegate :pluck, :ids, to: :all
13
17
 
14
18
  # Executes a custom SQL query against your database and returns all the results. The results will
15
19
  # be returned as an array with columns requested encapsulated as attributes of the model you call
16
20
  # this method from. If you call <tt>Product.find_by_sql</tt> then the results will be returned in
17
- # a Product object with the attributes you specified in the SQL query.
21
+ # a +Product+ object with the attributes you specified in the SQL query.
18
22
  #
19
23
  # If you call a complicated SQL query which spans multiple tables the columns specified by the
20
24
  # SELECT will be attributes of the model, whether or not they are columns of the corresponding
@@ -25,17 +29,27 @@ module ActiveRecord
25
29
  # MySQL specific terms will lock you to using that particular database engine or require you to
26
30
  # change your call if you switch engines.
27
31
  #
28
- # ==== Examples
29
32
  # # A simple SQL query spanning multiple tables
30
33
  # Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
31
- # > [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
34
+ # # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
35
+ #
36
+ # You can use the same string replacement techniques as you can with <tt>ActiveRecord::QueryMethods#where</tt>:
32
37
  #
33
- # # You can use the same string replacement techniques as you can with ActiveRecord#find
34
38
  # Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
35
- # > [#<Post:0x36bff9c @attributes={"title"=>"The Cheap Man Buys Twice"}>, ...]
36
- def find_by_sql(sql, binds = [])
37
- logging_query_plan do
38
- connection.select_all(sanitize_sql(sql), "#{name} Load", binds).collect! { |record| instantiate(record) }
39
+ # Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
40
+ def find_by_sql(sql, binds = [], preparable: nil, &block)
41
+ result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
42
+ column_types = result_set.column_types.dup
43
+ attribute_types.each_key { |k| column_types.delete k }
44
+ message_bus = ActiveSupport::Notifications.instrumenter
45
+
46
+ payload = {
47
+ record_count: result_set.length,
48
+ class_name: name
49
+ }
50
+
51
+ message_bus.instrument("instantiation.active_record", payload) do
52
+ result_set.map { |record| instantiate(record, column_types, &block) }
39
53
  end
40
54
  end
41
55
 
@@ -43,16 +57,14 @@ module ActiveRecord
43
57
  # The use of this method should be restricted to complicated SQL queries that can't be executed
44
58
  # using the ActiveRecord::Calculations class methods. Look into those before using this.
45
59
  #
46
- # ==== Parameters
47
- #
48
- # * +sql+ - An SQL statement which should return a count query from the database, see the example below.
60
+ # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
61
+ # # => 12
49
62
  #
50
- # ==== Examples
63
+ # ==== Parameters
51
64
  #
52
- # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
65
+ # * +sql+ - An SQL statement which should return a count query from the database, see the example above.
53
66
  def count_by_sql(sql)
54
- sql = sanitize_conditions(sql)
55
- connection.select_value(sql, "#{name} Count").to_i
67
+ connection.select_value(sanitize_sql(sql), "#{name} Count").to_i
56
68
  end
57
69
  end
58
70
  end
@@ -1,36 +1,51 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_record"
2
4
  require "rails"
3
5
  require "active_model/railtie"
4
6
 
5
7
  # For now, action_controller must always be present with
6
- # rails, so let's make sure that it gets required before
8
+ # Rails, so let's make sure that it gets required before
7
9
  # here. This is needed for correctly setting up the middleware.
8
10
  # In the future, this might become an optional require.
9
11
  require "action_controller/railtie"
10
12
 
11
13
  module ActiveRecord
12
14
  # = Active Record Railtie
13
- class Railtie < Rails::Railtie
15
+ class Railtie < Rails::Railtie # :nodoc:
14
16
  config.active_record = ActiveSupport::OrderedOptions.new
15
17
 
16
- config.app_generators.orm :active_record, :migration => true,
17
- :timestamps => true
18
-
19
- config.app_middleware.insert_after "::ActionDispatch::Callbacks",
20
- "ActiveRecord::QueryCache"
21
-
22
- config.app_middleware.insert_after "::ActionDispatch::Callbacks",
23
- "ActiveRecord::ConnectionAdapters::ConnectionManagement"
18
+ config.app_generators.orm :active_record, migration: true,
19
+ timestamps: true
24
20
 
25
21
  config.action_dispatch.rescue_responses.merge!(
26
- 'ActiveRecord::RecordNotFound' => :not_found,
27
- 'ActiveRecord::StaleObjectError' => :conflict,
28
- 'ActiveRecord::RecordInvalid' => :unprocessable_entity,
29
- 'ActiveRecord::RecordNotSaved' => :unprocessable_entity
22
+ "ActiveRecord::RecordNotFound" => :not_found,
23
+ "ActiveRecord::StaleObjectError" => :conflict,
24
+ "ActiveRecord::RecordInvalid" => :unprocessable_entity,
25
+ "ActiveRecord::RecordNotSaved" => :unprocessable_entity
30
26
  )
31
27
 
28
+ config.active_record.use_schema_cache_dump = true
29
+ config.active_record.maintain_test_schema = true
30
+
31
+ config.active_record.sqlite3 = ActiveSupport::OrderedOptions.new
32
+ config.active_record.sqlite3.represent_boolean_as_integer = nil
33
+
34
+ config.eager_load_namespaces << ActiveRecord
35
+
32
36
  rake_tasks do
33
- require "active_record/base"
37
+ namespace :db do
38
+ task :load_config do
39
+ ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
40
+
41
+ if defined?(ENGINE_ROOT) && engine = Rails::Engine.find(ENGINE_ROOT)
42
+ if engine.paths["db/migrate"].existent
43
+ ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths["db/migrate"].to_a
44
+ end
45
+ end
46
+ end
47
+ end
48
+
34
49
  load "active_record/railties/databases.rake"
35
50
  end
36
51
 
@@ -40,10 +55,14 @@ module ActiveRecord
40
55
  console do |app|
41
56
  require "active_record/railties/console_sandbox" if app.sandbox?
42
57
  require "active_record/base"
43
- ActiveRecord::Base.logger = Logger.new(STDERR)
58
+ unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
59
+ console = ActiveSupport::Logger.new(STDERR)
60
+ Rails.logger.extend ActiveSupport::Logger.broadcast console
61
+ end
62
+ ActiveRecord::Base.verbose_query_logs = false
44
63
  end
45
64
 
46
- runner do |app|
65
+ runner do
47
66
  require "active_record/base"
48
67
  end
49
68
 
@@ -58,17 +77,50 @@ module ActiveRecord
58
77
  ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
59
78
  end
60
79
 
61
- initializer "active_record.identity_map" do |app|
62
- config.app_middleware.insert_after "::ActionDispatch::Callbacks",
63
- "ActiveRecord::IdentityMap::Middleware" if config.active_record.delete(:identity_map)
80
+ initializer "active_record.migration_error" do
81
+ if config.active_record.delete(:migration_error) == :page_load
82
+ config.app_middleware.insert_after ::ActionDispatch::Callbacks,
83
+ ActiveRecord::Migration::CheckPending
84
+ end
85
+ end
86
+
87
+ initializer "active_record.check_schema_cache_dump" do
88
+ if config.active_record.delete(:use_schema_cache_dump)
89
+ config.after_initialize do |app|
90
+ ActiveSupport.on_load(:active_record) do
91
+ filename = File.join(app.config.paths["db"].first, "schema_cache.yml")
92
+
93
+ if File.file?(filename)
94
+ current_version = ActiveRecord::Migrator.current_version
95
+
96
+ next if current_version.nil?
97
+
98
+ cache = YAML.load(File.read(filename))
99
+ if cache.version == current_version
100
+ connection.schema_cache = cache
101
+ connection_pool.schema_cache = cache.dup
102
+ else
103
+ warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ initializer "active_record.warn_on_records_fetched_greater_than" do
112
+ if config.active_record.warn_on_records_fetched_greater_than
113
+ ActiveSupport.on_load(:active_record) do
114
+ require "active_record/relation/record_fetch_warning"
115
+ end
116
+ end
64
117
  end
65
118
 
66
119
  initializer "active_record.set_configs" do |app|
67
120
  ActiveSupport.on_load(:active_record) do
68
- if app.config.active_record.delete(:whitelist_attributes)
69
- attr_accessible(nil)
70
- end
71
- app.config.active_record.each do |k,v|
121
+ configs = app.config.active_record.dup
122
+ configs.delete(:sqlite3)
123
+ configs.each do |k, v|
72
124
  send "#{k}=", v
73
125
  end
74
126
  end
@@ -76,54 +128,97 @@ module ActiveRecord
76
128
 
77
129
  # This sets the database configuration from Configuration#database_configuration
78
130
  # and then establishes the connection.
79
- initializer "active_record.initialize_database" do |app|
131
+ initializer "active_record.initialize_database" do
80
132
  ActiveSupport.on_load(:active_record) do
81
- db_connection_type = "DATABASE_URL"
82
- unless ENV['DATABASE_URL']
83
- db_connection_type = "database.yml"
84
- self.configurations = app.config.database_configuration
85
- end
86
- Rails.logger.info "Connecting to database specified by #{db_connection_type}"
133
+ self.configurations = Rails.application.config.database_configuration
134
+
135
+ begin
136
+ establish_connection
137
+ rescue ActiveRecord::NoDatabaseError
138
+ warn <<-end_warning
139
+ Oops - You have a database configured, but it doesn't exist yet!
140
+
141
+ Here's how to get started:
87
142
 
88
- establish_connection
143
+ 1. Configure your database in config/database.yml.
144
+ 2. Run `bin/rails db:create` to create the database.
145
+ 3. Run `bin/rails db:setup` to load your database schema.
146
+ end_warning
147
+ raise
148
+ end
89
149
  end
90
150
  end
91
151
 
92
152
  # Expose database runtime to controller for logging.
93
- initializer "active_record.log_runtime" do |app|
153
+ initializer "active_record.log_runtime" do
94
154
  require "active_record/railties/controller_runtime"
95
155
  ActiveSupport.on_load(:action_controller) do
96
156
  include ActiveRecord::Railties::ControllerRuntime
97
157
  end
98
158
  end
99
159
 
100
- initializer "active_record.set_reloader_hooks" do |app|
101
- hook = lambda do
102
- ActiveRecord::Base.clear_reloadable_connections!
103
- ActiveRecord::Base.clear_cache!
104
- end
105
-
106
- if app.config.reload_classes_only_on_change
107
- ActiveSupport.on_load(:active_record) do
108
- ActionDispatch::Reloader.to_prepare(&hook)
109
- end
110
- else
111
- ActiveSupport.on_load(:active_record) do
112
- ActionDispatch::Reloader.to_cleanup(&hook)
160
+ initializer "active_record.set_reloader_hooks" do
161
+ ActiveSupport.on_load(:active_record) do
162
+ ActiveSupport::Reloader.before_class_unload do
163
+ if ActiveRecord::Base.connected?
164
+ ActiveRecord::Base.clear_cache!
165
+ ActiveRecord::Base.clear_reloadable_connections!
166
+ end
113
167
  end
114
168
  end
115
169
  end
116
170
 
171
+ initializer "active_record.set_executor_hooks" do
172
+ ActiveRecord::QueryCache.install_executor_hooks
173
+ end
174
+
117
175
  initializer "active_record.add_watchable_files" do |app|
118
- config.watchable_files.concat ["#{app.root}/db/schema.rb", "#{app.root}/db/structure.sql"]
176
+ path = app.paths["db"].first
177
+ config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"]
119
178
  end
120
179
 
121
- config.after_initialize do
122
- ActiveSupport.on_load(:active_record) do
123
- instantiate_observers
180
+ initializer "active_record.clear_active_connections" do
181
+ config.after_initialize do
182
+ ActiveSupport.on_load(:active_record) do
183
+ # Ideally the application doesn't connect to the database during boot,
184
+ # but sometimes it does. In case it did, we want to empty out the
185
+ # connection pools so that a non-database-using process (e.g. a master
186
+ # process in a forking server model) doesn't retain a needless
187
+ # connection. If it was needed, the incremental cost of reestablishing
188
+ # this connection is trivial: the rest of the pool would need to be
189
+ # populated anyway.
190
+
191
+ clear_active_connections!
192
+ flush_idle_connections!
193
+ end
194
+ end
195
+ end
124
196
 
125
- ActionDispatch::Reloader.to_prepare do
126
- ActiveRecord::Base.instantiate_observers
197
+ initializer "active_record.check_represent_sqlite3_boolean_as_integer" do
198
+ config.after_initialize do
199
+ ActiveSupport.on_load(:active_record_sqlite3adapter) do
200
+ represent_boolean_as_integer = Rails.application.config.active_record.sqlite3.delete(:represent_boolean_as_integer)
201
+ unless represent_boolean_as_integer.nil?
202
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = represent_boolean_as_integer
203
+ end
204
+
205
+ unless ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer
206
+ ActiveSupport::Deprecation.warn <<-MSG
207
+ Leaving `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer`
208
+ set to false is deprecated. SQLite databases have used 't' and 'f' to serialize
209
+ boolean values and must have old data converted to 1 and 0 (its native boolean
210
+ serialization) before setting this flag to true. Conversion can be accomplished
211
+ by setting up a rake task which runs
212
+
213
+ ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
214
+ ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
215
+
216
+ for all models and all boolean columns, after which the flag must be set to
217
+ true by adding the following to your application.rb file:
218
+
219
+ Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
220
+ MSG
221
+ end
127
222
  end
128
223
  end
129
224
  end
@@ -1,6 +1,7 @@
1
- ActiveRecord::Base.connection.increment_open_transactions
2
- ActiveRecord::Base.connection.begin_db_transaction
1
+ # frozen_string_literal: true
2
+
3
+ ActiveRecord::Base.connection.begin_transaction(joinable: false)
4
+
3
5
  at_exit do
4
- ActiveRecord::Base.connection.rollback_db_transaction
5
- ActiveRecord::Base.connection.decrement_open_transactions
6
+ ActiveRecord::Base.connection.rollback_transaction
6
7
  end
@@ -1,15 +1,21 @@
1
- require 'active_support/core_ext/module/attr_internal'
2
- require 'active_record/log_subscriber'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/attr_internal"
4
+ require "active_record/log_subscriber"
3
5
 
4
6
  module ActiveRecord
5
- module Railties
7
+ module Railties # :nodoc:
6
8
  module ControllerRuntime #:nodoc:
7
9
  extend ActiveSupport::Concern
8
10
 
11
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
12
+ # Workaround for Ruby 2.2 "private attribute?" warning.
9
13
  protected
10
14
 
11
15
  attr_internal :db_runtime
12
16
 
17
+ private
18
+
13
19
  def process_action(action, *args)
14
20
  # We also need to reset the runtime before each action
15
21
  # because of queries in middleware or in cases we are streaming
@@ -19,11 +25,12 @@ module ActiveRecord
19
25
  end
20
26
 
21
27
  def cleanup_view_runtime
22
- if ActiveRecord::Base.connected?
28
+ if logger && logger.info? && ActiveRecord::Base.connected?
23
29
  db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
30
+ self.db_runtime = (db_runtime || 0) + db_rt_before_render
24
31
  runtime = super
25
32
  db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
26
- self.db_runtime = db_rt_before_render + db_rt_after_render
33
+ self.db_runtime += db_rt_after_render
27
34
  runtime - db_rt_after_render
28
35
  else
29
36
  super
@@ -37,7 +44,7 @@ module ActiveRecord
37
44
  end
38
45
  end
39
46
 
40
- module ClassMethods
47
+ module ClassMethods # :nodoc:
41
48
  def log_process_action(payload)
42
49
  messages, db_runtime = super, payload[:db_runtime]
43
50
  messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime