activerecord 3.2.19 → 5.0.0

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 (264) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1715 -604
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +40 -45
  5. data/examples/performance.rb +33 -22
  6. data/examples/simple.rb +3 -4
  7. data/lib/active_record/aggregations.rb +76 -51
  8. data/lib/active_record/association_relation.rb +35 -0
  9. data/lib/active_record/associations/alias_tracker.rb +54 -40
  10. data/lib/active_record/associations/association.rb +76 -56
  11. data/lib/active_record/associations/association_scope.rb +125 -93
  12. data/lib/active_record/associations/belongs_to_association.rb +57 -28
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
  14. data/lib/active_record/associations/builder/association.rb +120 -32
  15. data/lib/active_record/associations/builder/belongs_to.rb +115 -62
  16. data/lib/active_record/associations/builder/collection_association.rb +61 -53
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +117 -43
  18. data/lib/active_record/associations/builder/has_many.rb +9 -65
  19. data/lib/active_record/associations/builder/has_one.rb +18 -52
  20. data/lib/active_record/associations/builder/singular_association.rb +18 -19
  21. data/lib/active_record/associations/collection_association.rb +268 -186
  22. data/lib/active_record/associations/collection_proxy.rb +1003 -63
  23. data/lib/active_record/associations/foreign_association.rb +11 -0
  24. data/lib/active_record/associations/has_many_association.rb +81 -41
  25. data/lib/active_record/associations/has_many_through_association.rb +76 -55
  26. data/lib/active_record/associations/has_one_association.rb +51 -21
  27. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  28. data/lib/active_record/associations/join_dependency/join_association.rb +83 -108
  29. data/lib/active_record/associations/join_dependency/join_base.rb +7 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +30 -37
  31. data/lib/active_record/associations/join_dependency.rb +239 -155
  32. data/lib/active_record/associations/preloader/association.rb +97 -62
  33. data/lib/active_record/associations/preloader/collection_association.rb +2 -8
  34. data/lib/active_record/associations/preloader/has_many_through.rb +7 -3
  35. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  36. data/lib/active_record/associations/preloader/singular_association.rb +3 -3
  37. data/lib/active_record/associations/preloader/through_association.rb +75 -33
  38. data/lib/active_record/associations/preloader.rb +111 -79
  39. data/lib/active_record/associations/singular_association.rb +35 -13
  40. data/lib/active_record/associations/through_association.rb +41 -19
  41. data/lib/active_record/associations.rb +727 -501
  42. data/lib/active_record/attribute/user_provided_default.rb +28 -0
  43. data/lib/active_record/attribute.rb +213 -0
  44. data/lib/active_record/attribute_assignment.rb +32 -162
  45. data/lib/active_record/attribute_decorators.rb +67 -0
  46. data/lib/active_record/attribute_methods/before_type_cast.rb +52 -7
  47. data/lib/active_record/attribute_methods/dirty.rb +101 -61
  48. data/lib/active_record/attribute_methods/primary_key.rb +50 -36
  49. data/lib/active_record/attribute_methods/query.rb +7 -6
  50. data/lib/active_record/attribute_methods/read.rb +56 -117
  51. data/lib/active_record/attribute_methods/serialization.rb +43 -96
  52. data/lib/active_record/attribute_methods/time_zone_conversion.rb +93 -42
  53. data/lib/active_record/attribute_methods/write.rb +34 -45
  54. data/lib/active_record/attribute_methods.rb +333 -144
  55. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  56. data/lib/active_record/attribute_set/builder.rb +108 -0
  57. data/lib/active_record/attribute_set.rb +108 -0
  58. data/lib/active_record/attributes.rb +265 -0
  59. data/lib/active_record/autosave_association.rb +285 -223
  60. data/lib/active_record/base.rb +95 -490
  61. data/lib/active_record/callbacks.rb +95 -61
  62. data/lib/active_record/coders/json.rb +13 -0
  63. data/lib/active_record/coders/yaml_column.rb +28 -19
  64. data/lib/active_record/collection_cache_key.rb +40 -0
  65. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +724 -277
  66. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  67. data/lib/active_record/connection_adapters/abstract/database_statements.rb +199 -192
  68. data/lib/active_record/connection_adapters/abstract/query_cache.rb +31 -26
  69. data/lib/active_record/connection_adapters/abstract/quoting.rb +140 -57
  70. data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +147 -0
  72. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +419 -276
  73. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +105 -0
  74. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +963 -276
  75. data/lib/active_record/connection_adapters/abstract/transaction.rb +232 -0
  76. data/lib/active_record/connection_adapters/abstract_adapter.rb +397 -106
  77. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +643 -342
  78. data/lib/active_record/connection_adapters/column.rb +30 -259
  79. data/lib/active_record/connection_adapters/connection_specification.rb +263 -0
  80. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  81. data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
  82. data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
  83. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
  84. data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
  85. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
  86. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
  87. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
  88. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
  89. data/lib/active_record/connection_adapters/mysql2_adapter.rb +47 -196
  90. data/lib/active_record/connection_adapters/postgresql/column.rb +15 -0
  91. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +170 -0
  92. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +70 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +48 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +21 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +10 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +39 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +93 -0
  109. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +15 -0
  110. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
  112. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
  113. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
  114. data/lib/active_record/connection_adapters/postgresql/oid.rb +31 -0
  115. data/lib/active_record/connection_adapters/postgresql/quoting.rb +116 -0
  116. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +49 -0
  117. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +180 -0
  118. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
  119. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +682 -0
  120. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  121. data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
  122. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -1039
  123. data/lib/active_record/connection_adapters/schema_cache.rb +74 -36
  124. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  125. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +538 -24
  129. data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
  130. data/lib/active_record/connection_handling.rb +155 -0
  131. data/lib/active_record/core.rb +561 -0
  132. data/lib/active_record/counter_cache.rb +146 -105
  133. data/lib/active_record/dynamic_matchers.rb +101 -64
  134. data/lib/active_record/enum.rb +234 -0
  135. data/lib/active_record/errors.rb +153 -56
  136. data/lib/active_record/explain.rb +15 -63
  137. data/lib/active_record/explain_registry.rb +30 -0
  138. data/lib/active_record/explain_subscriber.rb +10 -6
  139. data/lib/active_record/fixture_set/file.rb +77 -0
  140. data/lib/active_record/fixtures.rb +355 -232
  141. data/lib/active_record/gem_version.rb +15 -0
  142. data/lib/active_record/inheritance.rb +144 -79
  143. data/lib/active_record/integration.rb +66 -13
  144. data/lib/active_record/internal_metadata.rb +56 -0
  145. data/lib/active_record/legacy_yaml_adapter.rb +46 -0
  146. data/lib/active_record/locale/en.yml +9 -1
  147. data/lib/active_record/locking/optimistic.rb +77 -56
  148. data/lib/active_record/locking/pessimistic.rb +6 -6
  149. data/lib/active_record/log_subscriber.rb +53 -28
  150. data/lib/active_record/migration/command_recorder.rb +166 -33
  151. data/lib/active_record/migration/compatibility.rb +126 -0
  152. data/lib/active_record/migration/join_table.rb +15 -0
  153. data/lib/active_record/migration.rb +792 -264
  154. data/lib/active_record/model_schema.rb +192 -130
  155. data/lib/active_record/nested_attributes.rb +238 -145
  156. data/lib/active_record/no_touching.rb +52 -0
  157. data/lib/active_record/null_relation.rb +89 -0
  158. data/lib/active_record/persistence.rb +357 -157
  159. data/lib/active_record/query_cache.rb +22 -43
  160. data/lib/active_record/querying.rb +34 -23
  161. data/lib/active_record/railtie.rb +88 -48
  162. data/lib/active_record/railties/console_sandbox.rb +3 -4
  163. data/lib/active_record/railties/controller_runtime.rb +5 -4
  164. data/lib/active_record/railties/databases.rake +170 -422
  165. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  166. data/lib/active_record/readonly_attributes.rb +2 -5
  167. data/lib/active_record/reflection.rb +715 -189
  168. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  169. data/lib/active_record/relation/batches.rb +203 -50
  170. data/lib/active_record/relation/calculations.rb +203 -194
  171. data/lib/active_record/relation/delegation.rb +103 -25
  172. data/lib/active_record/relation/finder_methods.rb +457 -261
  173. data/lib/active_record/relation/from_clause.rb +32 -0
  174. data/lib/active_record/relation/merger.rb +167 -0
  175. data/lib/active_record/relation/predicate_builder/array_handler.rb +43 -0
  176. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
  177. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  178. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  179. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  180. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
  181. data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
  182. data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
  183. data/lib/active_record/relation/predicate_builder.rb +153 -48
  184. data/lib/active_record/relation/query_attribute.rb +19 -0
  185. data/lib/active_record/relation/query_methods.rb +1019 -194
  186. data/lib/active_record/relation/record_fetch_warning.rb +49 -0
  187. data/lib/active_record/relation/spawn_methods.rb +46 -150
  188. data/lib/active_record/relation/where_clause.rb +174 -0
  189. data/lib/active_record/relation/where_clause_factory.rb +38 -0
  190. data/lib/active_record/relation.rb +450 -245
  191. data/lib/active_record/result.rb +104 -12
  192. data/lib/active_record/runtime_registry.rb +22 -0
  193. data/lib/active_record/sanitization.rb +120 -94
  194. data/lib/active_record/schema.rb +28 -18
  195. data/lib/active_record/schema_dumper.rb +141 -74
  196. data/lib/active_record/schema_migration.rb +50 -0
  197. data/lib/active_record/scoping/default.rb +64 -57
  198. data/lib/active_record/scoping/named.rb +93 -108
  199. data/lib/active_record/scoping.rb +73 -121
  200. data/lib/active_record/secure_token.rb +38 -0
  201. data/lib/active_record/serialization.rb +7 -5
  202. data/lib/active_record/statement_cache.rb +113 -0
  203. data/lib/active_record/store.rb +173 -15
  204. data/lib/active_record/suppressor.rb +58 -0
  205. data/lib/active_record/table_metadata.rb +68 -0
  206. data/lib/active_record/tasks/database_tasks.rb +313 -0
  207. data/lib/active_record/tasks/mysql_database_tasks.rb +151 -0
  208. data/lib/active_record/tasks/postgresql_database_tasks.rb +110 -0
  209. data/lib/active_record/tasks/sqlite_database_tasks.rb +59 -0
  210. data/lib/active_record/timestamp.rb +42 -24
  211. data/lib/active_record/touch_later.rb +58 -0
  212. data/lib/active_record/transactions.rb +233 -105
  213. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  214. data/lib/active_record/type/date.rb +7 -0
  215. data/lib/active_record/type/date_time.rb +7 -0
  216. data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
  217. data/lib/active_record/type/internal/abstract_json.rb +29 -0
  218. data/lib/active_record/type/internal/timezone.rb +15 -0
  219. data/lib/active_record/type/serialized.rb +63 -0
  220. data/lib/active_record/type/time.rb +20 -0
  221. data/lib/active_record/type/type_map.rb +64 -0
  222. data/lib/active_record/type.rb +72 -0
  223. data/lib/active_record/type_caster/connection.rb +29 -0
  224. data/lib/active_record/type_caster/map.rb +19 -0
  225. data/lib/active_record/type_caster.rb +7 -0
  226. data/lib/active_record/validations/absence.rb +23 -0
  227. data/lib/active_record/validations/associated.rb +33 -18
  228. data/lib/active_record/validations/length.rb +24 -0
  229. data/lib/active_record/validations/presence.rb +66 -0
  230. data/lib/active_record/validations/uniqueness.rb +128 -68
  231. data/lib/active_record/validations.rb +48 -40
  232. data/lib/active_record/version.rb +5 -7
  233. data/lib/active_record.rb +71 -47
  234. data/lib/rails/generators/active_record/migration/migration_generator.rb +56 -8
  235. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +24 -0
  236. data/lib/rails/generators/active_record/migration/templates/migration.rb +28 -16
  237. data/lib/rails/generators/active_record/migration.rb +18 -8
  238. data/lib/rails/generators/active_record/model/model_generator.rb +38 -16
  239. data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
  240. data/lib/rails/generators/active_record/model/templates/model.rb +7 -6
  241. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  242. data/lib/rails/generators/active_record.rb +3 -11
  243. metadata +188 -134
  244. data/examples/associations.png +0 -0
  245. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  246. data/lib/active_record/associations/join_helper.rb +0 -55
  247. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  248. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  249. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  250. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -441
  251. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  252. data/lib/active_record/dynamic_finder_match.rb +0 -68
  253. data/lib/active_record/dynamic_scope_match.rb +0 -23
  254. data/lib/active_record/fixtures/file.rb +0 -65
  255. data/lib/active_record/identity_map.rb +0 -162
  256. data/lib/active_record/observer.rb +0 -121
  257. data/lib/active_record/serializers/xml_serializer.rb +0 -203
  258. data/lib/active_record/session_store.rb +0 -360
  259. data/lib/active_record/test_case.rb +0 -73
  260. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
  261. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  262. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  263. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  264. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,12 +1,11 @@
1
- require 'active_support/core_ext/object/blank'
2
-
3
1
  module ActiveRecord
4
2
  # = Active Record Query Cache
5
3
  class QueryCache
6
4
  module ClassMethods
7
5
  # Enable the query cache within the block if Active Record is configured.
6
+ # If it's not, it will execute the given block.
8
7
  def cache(&block)
9
- if ActiveRecord::Base.connected?
8
+ if connected?
10
9
  connection.cache(&block)
11
10
  else
12
11
  yield
@@ -14,8 +13,9 @@ module ActiveRecord
14
13
  end
15
14
 
16
15
  # Disable the query cache within the block if Active Record is configured.
16
+ # If it's not, it will execute the given block.
17
17
  def uncached(&block)
18
- if ActiveRecord::Base.connected?
18
+ if connected?
19
19
  connection.uncached(&block)
20
20
  else
21
21
  yield
@@ -23,52 +23,31 @@ module ActiveRecord
23
23
  end
24
24
  end
25
25
 
26
- def initialize(app)
27
- @app = app
28
- end
29
-
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
26
+ def self.run
27
+ connection = ActiveRecord::Base.connection
28
+ enabled = connection.query_cache_enabled
29
+ connection_id = ActiveRecord::Base.connection_id
30
+ connection.enable_query_cache!
36
31
 
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
32
+ [enabled, connection_id]
33
+ end
44
34
 
45
- def each(&block)
46
- @target.each(&block)
47
- end
35
+ def self.complete(state)
36
+ enabled, connection_id = state
48
37
 
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
57
- end
38
+ ActiveRecord::Base.connection_id = connection_id
39
+ ActiveRecord::Base.connection.clear_query_cache
40
+ ActiveRecord::Base.connection.disable_query_cache! unless enabled
58
41
  end
59
42
 
60
- def call(env)
61
- old = ActiveRecord::Base.connection.query_cache_enabled
62
- ActiveRecord::Base.connection.enable_query_cache!
43
+ def self.install_executor_hooks(executor = ActiveSupport::Executor)
44
+ executor.register_hook(self)
63
45
 
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!
46
+ executor.to_complete do
47
+ unless ActiveRecord::Base.connection.transaction_open?
48
+ ActiveRecord::Base.clear_active_connections!
49
+ end
70
50
  end
71
- raise e
72
51
  end
73
52
  end
74
53
  end
@@ -1,20 +1,22 @@
1
- require 'active_support/core_ext/module/delegation'
2
-
3
1
  module ActiveRecord
4
2
  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
3
+ delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :none?, :one?, to: :all
4
+ 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
5
+ delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
6
+ delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
7
+ delegate :find_by, :find_by!, to: :all
8
+ delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, to: :all
9
+ delegate :find_each, :find_in_batches, :in_batches, to: :all
10
+ delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
11
+ :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly,
12
+ :having, :create_with, :uniq, :distinct, :references, :none, :unscope, to: :all
13
+ delegate :count, :average, :minimum, :maximum, :sum, :calculate, to: :all
14
+ delegate :pluck, :ids, to: :all
13
15
 
14
16
  # Executes a custom SQL query against your database and returns all the results. The results will
15
17
  # be returned as an array with columns requested encapsulated as attributes of the model you call
16
18
  # 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.
19
+ # a +Product+ object with the attributes you specified in the SQL query.
18
20
  #
19
21
  # If you call a complicated SQL query which spans multiple tables the columns specified by the
20
22
  # SELECT will be attributes of the model, whether or not they are columns of the corresponding
@@ -25,17 +27,27 @@ module ActiveRecord
25
27
  # MySQL specific terms will lock you to using that particular database engine or require you to
26
28
  # change your call if you switch engines.
27
29
  #
28
- # ==== Examples
29
30
  # # A simple SQL query spanning multiple tables
30
31
  # 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"}>, ...]
32
+ # # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
33
+ #
34
+ # You can use the same string replacement techniques as you can with <tt>ActiveRecord::QueryMethods#where</tt>:
32
35
  #
33
- # # You can use the same string replacement techniques as you can with ActiveRecord#find
34
36
  # 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) }
37
+ # Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
38
+ def find_by_sql(sql, binds = [], preparable: nil)
39
+ result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
40
+ column_types = result_set.column_types.dup
41
+ columns_hash.each_key { |k| column_types.delete k }
42
+ message_bus = ActiveSupport::Notifications.instrumenter
43
+
44
+ payload = {
45
+ record_count: result_set.length,
46
+ class_name: name
47
+ }
48
+
49
+ message_bus.instrument('instantiation.active_record', payload) do
50
+ result_set.map { |record| instantiate(record, column_types) }
39
51
  end
40
52
  end
41
53
 
@@ -43,13 +55,12 @@ module ActiveRecord
43
55
  # The use of this method should be restricted to complicated SQL queries that can't be executed
44
56
  # using the ActiveRecord::Calculations class methods. Look into those before using this.
45
57
  #
46
- # ==== Parameters
47
- #
48
- # * +sql+ - An SQL statement which should return a count query from the database, see the example below.
58
+ # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
59
+ # # => 12
49
60
  #
50
- # ==== Examples
61
+ # ==== Parameters
51
62
  #
52
- # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
63
+ # * +sql+ - An SQL statement which should return a count query from the database, see the example above.
53
64
  def count_by_sql(sql)
54
65
  sql = sanitize_conditions(sql)
55
66
  connection.select_value(sql, "#{name} Count").to_i
@@ -10,18 +10,12 @@ require "action_controller/railtie"
10
10
 
11
11
  module ActiveRecord
12
12
  # = Active Record Railtie
13
- class Railtie < Rails::Railtie
13
+ class Railtie < Rails::Railtie # :nodoc:
14
14
  config.active_record = ActiveSupport::OrderedOptions.new
15
15
 
16
16
  config.app_generators.orm :active_record, :migration => true,
17
17
  :timestamps => true
18
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"
24
-
25
19
  config.action_dispatch.rescue_responses.merge!(
26
20
  'ActiveRecord::RecordNotFound' => :not_found,
27
21
  'ActiveRecord::StaleObjectError' => :conflict,
@@ -29,8 +23,25 @@ module ActiveRecord
29
23
  'ActiveRecord::RecordNotSaved' => :unprocessable_entity
30
24
  )
31
25
 
26
+
27
+ config.active_record.use_schema_cache_dump = true
28
+ config.active_record.maintain_test_schema = true
29
+
30
+ config.eager_load_namespaces << ActiveRecord
31
+
32
32
  rake_tasks do
33
- require "active_record/base"
33
+ namespace :db do
34
+ task :load_config do
35
+ ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
36
+
37
+ if defined?(ENGINE_ROOT) && engine = Rails::Engine.find(ENGINE_ROOT)
38
+ if engine.paths['db/migrate'].existent
39
+ ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths['db/migrate'].to_a
40
+ end
41
+ end
42
+ end
43
+ end
44
+
34
45
  load "active_record/railties/databases.rake"
35
46
  end
36
47
 
@@ -40,10 +51,13 @@ module ActiveRecord
40
51
  console do |app|
41
52
  require "active_record/railties/console_sandbox" if app.sandbox?
42
53
  require "active_record/base"
43
- ActiveRecord::Base.logger = Logger.new(STDERR)
54
+ unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
55
+ console = ActiveSupport::Logger.new(STDERR)
56
+ Rails.logger.extend ActiveSupport::Logger.broadcast console
57
+ end
44
58
  end
45
59
 
46
- runner do |app|
60
+ runner do
47
61
  require "active_record/base"
48
62
  end
49
63
 
@@ -58,16 +72,43 @@ module ActiveRecord
58
72
  ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
59
73
  end
60
74
 
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)
75
+ initializer "active_record.migration_error" do
76
+ if config.active_record.delete(:migration_error) == :page_load
77
+ config.app_middleware.insert_after ::ActionDispatch::Callbacks,
78
+ ActiveRecord::Migration::CheckPending
79
+ end
80
+ end
81
+
82
+ initializer "active_record.check_schema_cache_dump" do
83
+ if config.active_record.delete(:use_schema_cache_dump)
84
+ config.after_initialize do |app|
85
+ ActiveSupport.on_load(:active_record) do
86
+ filename = File.join(app.config.paths["db"].first, "schema_cache.dump")
87
+
88
+ if File.file?(filename)
89
+ cache = Marshal.load File.binread filename
90
+ if cache.version == ActiveRecord::Migrator.current_version
91
+ self.connection.schema_cache = cache
92
+ self.connection_pool.schema_cache = cache.dup
93
+ else
94
+ warn "Ignoring db/schema_cache.dump because it has expired. The current schema version is #{ActiveRecord::Migrator.current_version}, but the one in the cache is #{cache.version}."
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ initializer "active_record.warn_on_records_fetched_greater_than" do
103
+ if config.active_record.warn_on_records_fetched_greater_than
104
+ ActiveSupport.on_load(:active_record) do
105
+ require 'active_record/relation/record_fetch_warning'
106
+ end
107
+ end
64
108
  end
65
109
 
66
110
  initializer "active_record.set_configs" do |app|
67
111
  ActiveSupport.on_load(:active_record) do
68
- if app.config.active_record.delete(:whitelist_attributes)
69
- attr_accessible(nil)
70
- end
71
112
  app.config.active_record.each do |k,v|
72
113
  send "#{k}=", v
73
114
  end
@@ -76,56 +117,55 @@ module ActiveRecord
76
117
 
77
118
  # This sets the database configuration from Configuration#database_configuration
78
119
  # and then establishes the connection.
79
- initializer "active_record.initialize_database" do |app|
120
+ initializer "active_record.initialize_database" do
80
121
  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}"
122
+ self.configurations = Rails.application.config.database_configuration
123
+
124
+ begin
125
+ establish_connection
126
+ rescue ActiveRecord::NoDatabaseError
127
+ warn <<-end_warning
128
+ Oops - You have a database configured, but it doesn't exist yet!
87
129
 
88
- establish_connection
130
+ Here's how to get started:
131
+
132
+ 1. Configure your database in config/database.yml.
133
+ 2. Run `bin/rails db:create` to create the database.
134
+ 3. Run `bin/rails db:setup` to load your database schema.
135
+ end_warning
136
+ raise
137
+ end
89
138
  end
90
139
  end
91
140
 
92
141
  # Expose database runtime to controller for logging.
93
- initializer "active_record.log_runtime" do |app|
142
+ initializer "active_record.log_runtime" do
94
143
  require "active_record/railties/controller_runtime"
95
144
  ActiveSupport.on_load(:action_controller) do
96
145
  include ActiveRecord::Railties::ControllerRuntime
97
146
  end
98
147
  end
99
148
 
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)
149
+ initializer "active_record.set_reloader_hooks" do
150
+ ActiveSupport.on_load(:active_record) do
151
+ ActiveSupport::Reloader.before_class_unload do
152
+ if ActiveRecord::Base.connected?
153
+ ActiveRecord::Base.clear_cache!
154
+ ActiveRecord::Base.clear_reloadable_connections!
155
+ end
113
156
  end
114
157
  end
115
158
  end
116
159
 
117
- initializer "active_record.add_watchable_files" do |app|
118
- config.watchable_files.concat ["#{app.root}/db/schema.rb", "#{app.root}/db/structure.sql"]
119
- end
120
-
121
- config.after_initialize do
160
+ initializer "active_record.set_executor_hooks" do
122
161
  ActiveSupport.on_load(:active_record) do
123
- instantiate_observers
124
-
125
- ActionDispatch::Reloader.to_prepare do
126
- ActiveRecord::Base.instantiate_observers
127
- end
162
+ ActiveRecord::QueryCache.install_executor_hooks
128
163
  end
129
164
  end
165
+
166
+ initializer "active_record.add_watchable_files" do |app|
167
+ path = app.paths["db"].first
168
+ config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"]
169
+ end
130
170
  end
131
171
  end
@@ -1,6 +1,5 @@
1
- ActiveRecord::Base.connection.increment_open_transactions
2
- ActiveRecord::Base.connection.begin_db_transaction
1
+ ActiveRecord::Base.connection.begin_transaction(joinable: false)
2
+
3
3
  at_exit do
4
- ActiveRecord::Base.connection.rollback_db_transaction
5
- ActiveRecord::Base.connection.decrement_open_transactions
4
+ ActiveRecord::Base.connection.rollback_transaction
6
5
  end
@@ -2,7 +2,7 @@ require 'active_support/core_ext/module/attr_internal'
2
2
  require 'active_record/log_subscriber'
3
3
 
4
4
  module ActiveRecord
5
- module Railties
5
+ module Railties # :nodoc:
6
6
  module ControllerRuntime #:nodoc:
7
7
  extend ActiveSupport::Concern
8
8
 
@@ -19,11 +19,12 @@ module ActiveRecord
19
19
  end
20
20
 
21
21
  def cleanup_view_runtime
22
- if ActiveRecord::Base.connected?
22
+ if logger.info? && ActiveRecord::Base.connected?
23
23
  db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
24
+ self.db_runtime = (db_runtime || 0) + db_rt_before_render
24
25
  runtime = super
25
26
  db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
26
- self.db_runtime = db_rt_before_render + db_rt_after_render
27
+ self.db_runtime += db_rt_after_render
27
28
  runtime - db_rt_after_render
28
29
  else
29
30
  super
@@ -37,7 +38,7 @@ module ActiveRecord
37
38
  end
38
39
  end
39
40
 
40
- module ClassMethods
41
+ module ClassMethods # :nodoc:
41
42
  def log_process_action(payload)
42
43
  messages, db_runtime = super, payload[:db_runtime]
43
44
  messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime