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,5 +1,3 @@
1
- require 'active_support/concern'
2
-
3
1
  module ActiveRecord
4
2
  module ModelSchema
5
3
  extend ActiveSupport::Concern
@@ -12,8 +10,7 @@ module ActiveRecord
12
10
  # the Product class will look for "productid" instead of "id" as the primary column. If the
13
11
  # latter is specified, the Product class will look for "product_id" instead of "id". Remember
14
12
  # that this is a global setting for all Active Records.
15
- cattr_accessor :primary_key_prefix_type, :instance_writer => false
16
- self.primary_key_prefix_type = nil
13
+ mattr_accessor :primary_key_prefix_type, instance_writer: false
17
14
 
18
15
  ##
19
16
  # :singleton-method:
@@ -25,23 +22,68 @@ module ActiveRecord
25
22
  # If you are organising your models within modules you can add a prefix to the models within
26
23
  # a namespace by defining a singleton method in the parent module called table_name_prefix which
27
24
  # returns your chosen prefix.
28
- class_attribute :table_name_prefix, :instance_writer => false
25
+ class_attribute :table_name_prefix, instance_writer: false
29
26
  self.table_name_prefix = ""
30
27
 
31
28
  ##
32
29
  # :singleton-method:
33
30
  # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
34
31
  # "people_basecamp"). By default, the suffix is the empty string.
35
- class_attribute :table_name_suffix, :instance_writer => false
32
+ #
33
+ # If you are organising your models within modules, you can add a suffix to the models within
34
+ # a namespace by defining a singleton method in the parent module called table_name_suffix which
35
+ # returns your chosen suffix.
36
+ class_attribute :table_name_suffix, instance_writer: false
36
37
  self.table_name_suffix = ""
37
38
 
39
+ ##
40
+ # :singleton-method:
41
+ # Accessor for the name of the schema migrations table. By default, the value is "schema_migrations"
42
+ class_attribute :schema_migrations_table_name, instance_accessor: false
43
+ self.schema_migrations_table_name = "schema_migrations"
44
+
45
+ ##
46
+ # :singleton-method:
47
+ # Accessor for the name of the internal metadata table. By default, the value is "ar_internal_metadata"
48
+ class_attribute :internal_metadata_table_name, instance_accessor: false
49
+ self.internal_metadata_table_name = "ar_internal_metadata"
50
+
51
+ ##
52
+ # :singleton-method:
53
+ # Accessor for an array of names of environments where destructive actions should be prohibited. By default,
54
+ # the value is ["production"]
55
+ class_attribute :protected_environments, instance_accessor: false
56
+ self.protected_environments = ["production"]
57
+
38
58
  ##
39
59
  # :singleton-method:
40
60
  # Indicates whether table names should be the pluralized versions of the corresponding class names.
41
61
  # If true, the default table name for a Product class will be +products+. If false, it would just be +product+.
42
62
  # See table_name for the full rules on table/class naming. This is true, by default.
43
- class_attribute :pluralize_table_names, :instance_writer => false
63
+ class_attribute :pluralize_table_names, instance_writer: false
44
64
  self.pluralize_table_names = true
65
+
66
+ ##
67
+ # :singleton-method:
68
+ # Accessor for the list of columns names the model should ignore. Ignored columns won't have attribute
69
+ # accessors defined, and won't be referenced in SQL queries.
70
+ class_attribute :ignored_columns, instance_accessor: false
71
+ self.ignored_columns = [].freeze
72
+
73
+ self.inheritance_column = 'type'
74
+
75
+ delegate :type_for_attribute, to: :class
76
+ end
77
+
78
+ # Derives the join table name for +first_table+ and +second_table+. The
79
+ # table names appear in alphabetical order. A common prefix is removed
80
+ # (useful for namespaced models like Music::Artist and Music::Record):
81
+ #
82
+ # artists, records => artists_records
83
+ # records, artists => artists_records
84
+ # music_artists, music_records => music_artists_records
85
+ def self.derive_join_table_name(first_table, second_table) # :nodoc:
86
+ [first_table.to_s, second_table.to_s].sort.join("\0").gsub(/^(.*_)(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_")
45
87
  end
46
88
 
47
89
  module ClassMethods
@@ -89,47 +131,29 @@ module ActiveRecord
89
131
  # class Mouse < ActiveRecord::Base
90
132
  # self.table_name = "mice"
91
133
  # end
92
- #
93
- # Alternatively, you can override the table_name method to define your
94
- # own computation. (Possibly using <tt>super</tt> to manipulate the default
95
- # table name.) Example:
96
- #
97
- # class Post < ActiveRecord::Base
98
- # def self.table_name
99
- # "special_" + super
100
- # end
101
- # end
102
- # Post.table_name # => "special_posts"
103
134
  def table_name
104
135
  reset_table_name unless defined?(@table_name)
105
136
  @table_name
106
137
  end
107
138
 
108
- def original_table_name #:nodoc:
109
- deprecated_original_property_getter :table_name
110
- end
111
-
112
139
  # Sets the table name explicitly. Example:
113
140
  #
114
141
  # class Project < ActiveRecord::Base
115
142
  # self.table_name = "project"
116
143
  # end
117
- #
118
- # You can also just define your own <tt>self.table_name</tt> method; see
119
- # the documentation for ActiveRecord::Base#table_name.
120
144
  def table_name=(value)
121
- @original_table_name = @table_name if defined?(@table_name)
122
- @table_name = value && value.to_s
123
- @quoted_table_name = nil
124
- @arel_table = nil
125
- @relation = Relation.new(self, arel_table)
126
- end
145
+ value = value && value.to_s
146
+
147
+ if defined?(@table_name)
148
+ return if value == @table_name
149
+ reset_column_information if connected?
150
+ end
127
151
 
128
- def set_table_name(value = nil, &block) #:nodoc:
129
- deprecated_property_setter :table_name, value, block
152
+ @table_name = value
130
153
  @quoted_table_name = nil
131
154
  @arel_table = nil
132
- @relation = Relation.new(self, arel_table)
155
+ @sequence_name = nil unless defined?(@explicit_sequence_name) && @explicit_sequence_name
156
+ @predicate_builder = nil
133
157
  end
134
158
 
135
159
  # Returns a quoted version of the table name, used to construct SQL statements.
@@ -139,16 +163,12 @@ module ActiveRecord
139
163
 
140
164
  # Computes the table name, (re)sets it internally, and returns it.
141
165
  def reset_table_name #:nodoc:
142
- if abstract_class?
143
- self.table_name = if superclass == Base || superclass.abstract_class?
144
- nil
145
- else
146
- superclass.table_name
147
- end
166
+ self.table_name = if abstract_class?
167
+ superclass == Base ? nil : superclass.table_name
148
168
  elsif superclass.abstract_class?
149
- self.table_name = superclass.table_name || compute_table_name
169
+ superclass.table_name || compute_table_name
150
170
  else
151
- self.table_name = compute_table_name
171
+ compute_table_name
152
172
  end
153
173
  end
154
174
 
@@ -156,30 +176,29 @@ module ActiveRecord
156
176
  (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
157
177
  end
158
178
 
159
- # The name of the column containing the object's class when Single Table Inheritance is used
160
- def inheritance_column
161
- if self == Base
162
- (@inheritance_column ||= nil) || 'type'
163
- else
164
- (@inheritance_column ||= nil) || superclass.inheritance_column
165
- end
179
+ def full_table_name_suffix #:nodoc:
180
+ (parents.detect {|p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
166
181
  end
167
182
 
168
- def original_inheritance_column #:nodoc:
169
- deprecated_original_property_getter :inheritance_column
183
+ # Defines the name of the table column which will store the class name on single-table
184
+ # inheritance situations.
185
+ #
186
+ # The default inheritance column name is +type+, which means it's a
187
+ # reserved word inside Active Record. To be able to use single-table
188
+ # inheritance with another column name, or to use the column +type+ in
189
+ # your own model for something else, you can set +inheritance_column+:
190
+ #
191
+ # self.inheritance_column = 'zoink'
192
+ def inheritance_column
193
+ (@inheritance_column ||= nil) || superclass.inheritance_column
170
194
  end
171
195
 
172
196
  # Sets the value of inheritance_column
173
197
  def inheritance_column=(value)
174
- @original_inheritance_column = inheritance_column
175
- @inheritance_column = value.to_s
198
+ @inheritance_column = value.to_s
176
199
  @explicit_inheritance_column = true
177
200
  end
178
201
 
179
- def set_inheritance_column(value = nil, &block) #:nodoc:
180
- deprecated_property_setter :inheritance_column, value, block
181
- end
182
-
183
202
  def sequence_name
184
203
  if base_class == self
185
204
  @sequence_name ||= reset_sequence_name
@@ -188,12 +207,9 @@ module ActiveRecord
188
207
  end
189
208
  end
190
209
 
191
- def original_sequence_name #:nodoc:
192
- deprecated_original_property_getter :sequence_name
193
- end
194
-
195
210
  def reset_sequence_name #:nodoc:
196
- self.sequence_name = connection.default_sequence_name(table_name, primary_key)
211
+ @explicit_sequence_name = false
212
+ @sequence_name = connection.default_sequence_name(table_name, primary_key)
197
213
  end
198
214
 
199
215
  # Sets the name of the sequence to use when generating ids to the given
@@ -201,7 +217,7 @@ module ActiveRecord
201
217
  # given block. This is required for Oracle and is useful for any
202
218
  # database which relies on sequences for primary key generation.
203
219
  #
204
- # If a sequence name is not explicitly set when using Oracle or Firebird,
220
+ # If a sequence name is not explicitly set when using Oracle,
205
221
  # it will default to the commonly used pattern of: #{table_name}_seq
206
222
  #
207
223
  # If a sequence name is not explicitly set when using PostgreSQL, it
@@ -211,62 +227,81 @@ module ActiveRecord
211
227
  # self.sequence_name = "projectseq" # default would have been "project_seq"
212
228
  # end
213
229
  def sequence_name=(value)
214
- @original_sequence_name = @sequence_name if defined?(@sequence_name)
215
230
  @sequence_name = value.to_s
231
+ @explicit_sequence_name = true
216
232
  end
217
233
 
218
- def set_sequence_name(value = nil, &block) #:nodoc:
219
- deprecated_property_setter :sequence_name, value, block
234
+ # Determines if the primary key values should be selected from their
235
+ # corresponding sequence before the insert statement.
236
+ def prefetch_primary_key?
237
+ connection.prefetch_primary_key?(table_name)
238
+ end
239
+
240
+ # Returns the next value that will be used as the primary key on
241
+ # an insert statement.
242
+ def next_sequence_value
243
+ connection.next_sequence_value(sequence_name)
220
244
  end
221
245
 
222
246
  # Indicates whether the table associated with this class exists
223
247
  def table_exists?
224
- connection.schema_cache.table_exists?(table_name)
248
+ connection.schema_cache.data_source_exists?(table_name)
249
+ end
250
+
251
+ def attributes_builder # :nodoc:
252
+ @attributes_builder ||= AttributeSet::Builder.new(attribute_types, primary_key)
253
+ end
254
+
255
+ def columns_hash # :nodoc:
256
+ load_schema
257
+ @columns_hash
225
258
  end
226
259
 
227
- # Returns an array of column objects for the table associated with this class.
228
260
  def columns
229
- @columns ||= connection.schema_cache.columns[table_name].map do |col|
230
- col = col.dup
231
- col.primary = (col.name == primary_key)
232
- col
233
- end
261
+ load_schema
262
+ @columns ||= columns_hash.values
263
+ end
264
+
265
+ def attribute_types # :nodoc:
266
+ load_schema
267
+ @attribute_types ||= Hash.new(Type::Value.new)
234
268
  end
235
269
 
236
- # Returns a hash of column objects for the table associated with this class.
237
- def columns_hash
238
- @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
270
+ # Returns the type of the attribute with the given name, after applying
271
+ # all modifiers. This method is the only valid source of information for
272
+ # anything related to the types of a model's attributes. This method will
273
+ # access the database and load the model's schema if it is required.
274
+ #
275
+ # The return value of this method will implement the interface described
276
+ # by ActiveModel::Type::Value (though the object itself may not subclass
277
+ # it).
278
+ #
279
+ # +attr_name+ The name of the attribute to retrieve the type for. Must be
280
+ # a string
281
+ def type_for_attribute(attr_name)
282
+ attribute_types[attr_name]
239
283
  end
240
284
 
241
285
  # Returns a hash where the keys are column names and the values are
242
- # default values when instantiating the AR object for this table.
286
+ # default values when instantiating the Active Record object for this table.
243
287
  def column_defaults
244
- @column_defaults ||= Hash[columns.map { |c| [c.name, c.default] }]
288
+ load_schema
289
+ _default_attributes.to_hash
290
+ end
291
+
292
+ def _default_attributes # :nodoc:
293
+ @default_attributes ||= AttributeSet.new({})
245
294
  end
246
295
 
247
296
  # Returns an array of column names as strings.
248
297
  def column_names
249
- @column_names ||= columns.map { |column| column.name }
298
+ @column_names ||= columns.map(&:name)
250
299
  end
251
300
 
252
301
  # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
253
302
  # and columns used for single table inheritance have been removed.
254
303
  def content_columns
255
- @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
256
- end
257
-
258
- # Returns a hash of all the methods added to query each of the columns in the table with the name of the method as the key
259
- # and true as the value. This makes it possible to do O(1) lookups in respond_to? to check if a given method for attribute
260
- # is available.
261
- def column_methods_hash #:nodoc:
262
- @dynamic_methods_hash ||= column_names.inject(Hash.new(false)) do |methods, attr|
263
- attr_name = attr.to_s
264
- methods[attr.to_sym] = attr_name
265
- methods["#{attr}=".to_sym] = attr_name
266
- methods["#{attr}?".to_sym] = attr_name
267
- methods["#{attr}_before_type_cast".to_sym] = attr_name
268
- methods
269
- end
304
+ @content_columns ||= columns.reject { |c| c.name == primary_key || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
270
305
  end
271
306
 
272
307
  # Resets all the cached information about columns, which will cause them
@@ -276,7 +311,7 @@ module ActiveRecord
276
311
  # when just after creating a table you want to populate it with some default
277
312
  # values, eg:
278
313
  #
279
- # class CreateJobLevels < ActiveRecord::Migration
314
+ # class CreateJobLevels < ActiveRecord::Migration[5.0]
280
315
  # def up
281
316
  # create_table :job_levels do |t|
282
317
  # t.integer :id
@@ -287,7 +322,7 @@ module ActiveRecord
287
322
  #
288
323
  # JobLevel.reset_column_information
289
324
  # %w{assistant executive manager director}.each do |type|
290
- # JobLevel.create(:name => type)
325
+ # JobLevel.create(name: type)
291
326
  # end
292
327
  # end
293
328
  #
@@ -298,25 +333,57 @@ module ActiveRecord
298
333
  def reset_column_information
299
334
  connection.clear_cache!
300
335
  undefine_attribute_methods
301
- connection.schema_cache.clear_table_cache!(table_name) if table_exists?
336
+ connection.schema_cache.clear_data_source_cache!(table_name)
302
337
 
303
- @column_names = @content_columns = @column_defaults = @columns = @columns_hash = nil
304
- @dynamic_methods_hash = nil
305
- @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
306
- @arel_engine = @relation = nil
338
+ reload_schema_from_cache
307
339
  end
308
340
 
309
- def clear_cache! # :nodoc:
310
- connection.schema_cache.clear!
341
+ private
342
+
343
+ def schema_loaded?
344
+ defined?(@columns_hash) && @columns_hash
311
345
  end
312
346
 
313
- private
347
+ def load_schema
348
+ unless schema_loaded?
349
+ load_schema!
350
+ end
351
+ end
352
+
353
+ def load_schema!
354
+ @columns_hash = connection.schema_cache.columns_hash(table_name).except(*ignored_columns)
355
+ @columns_hash.each do |name, column|
356
+ warn_if_deprecated_type(column)
357
+ define_attribute(
358
+ name,
359
+ connection.lookup_cast_type_from_column(column),
360
+ default: column.default,
361
+ user_provided_default: false
362
+ )
363
+ end
364
+ end
365
+
366
+ def reload_schema_from_cache
367
+ @arel_engine = nil
368
+ @arel_table = nil
369
+ @column_names = nil
370
+ @attribute_types = nil
371
+ @content_columns = nil
372
+ @default_attributes = nil
373
+ @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
374
+ @attributes_builder = nil
375
+ @columns = nil
376
+ @columns_hash = nil
377
+ @attribute_names = nil
378
+ direct_descendants.each do |descendant|
379
+ descendant.send(:reload_schema_from_cache)
380
+ end
381
+ end
314
382
 
315
383
  # Guesses the table name, but does not decorate it with prefix and suffix information.
316
384
  def undecorated_table_name(class_name = base_class.name)
317
385
  table_name = class_name.to_s.demodulize.underscore
318
- table_name = table_name.pluralize if pluralize_table_names
319
- table_name
386
+ pluralize_table_names ? table_name.pluralize : table_name
320
387
  end
321
388
 
322
389
  # Computes and returns a table name according to default conventions.
@@ -324,43 +391,38 @@ module ActiveRecord
324
391
  base = base_class
325
392
  if self == base
326
393
  # Nested classes are prefixed with singular parent table name.
327
- if parent < ActiveRecord::Base && !parent.abstract_class?
394
+ if parent < Base && !parent.abstract_class?
328
395
  contained = parent.table_name
329
396
  contained = contained.singularize if parent.pluralize_table_names
330
397
  contained += '_'
331
398
  end
332
- "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{table_name_suffix}"
399
+
400
+ "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
333
401
  else
334
402
  # STI subclasses always use their superclass' table.
335
403
  base.table_name
336
404
  end
337
405
  end
338
406
 
339
- def deprecated_property_setter(property, value, block)
340
- if block
341
- ActiveSupport::Deprecation.warn(
342
- "Calling set_#{property} is deprecated. If you need to lazily evaluate " \
343
- "the #{property}, define your own `self.#{property}` class method. You can use `super` " \
344
- "to get the default #{property} where you would have called `original_#{property}`."
345
- )
346
-
347
- define_attr_method property, value, false, &block
348
- else
349
- ActiveSupport::Deprecation.warn(
350
- "Calling set_#{property} is deprecated. Please use `self.#{property} = 'the_name'` instead."
351
- )
407
+ def warn_if_deprecated_type(column)
408
+ return if attributes_to_define_after_schema_loads.key?(column.name)
409
+ if column.respond_to?(:oid) && column.sql_type.start_with?("point")
410
+ if column.array?
411
+ array_arguments = ", array: true"
412
+ else
413
+ array_arguments = ""
414
+ end
415
+ ActiveSupport::Deprecation.warn(<<-WARNING.strip_heredoc)
416
+ The behavior of the `:point` type will be changing in Rails 5.1 to
417
+ return a `Point` object, rather than an `Array`. If you'd like to
418
+ keep the old behavior, you can add this line to #{self.name}:
352
419
 
353
- define_attr_method property, value, false
354
- end
355
- end
420
+ attribute :#{column.name}, :legacy_point#{array_arguments}
356
421
 
357
- def deprecated_original_property_getter(property)
358
- ActiveSupport::Deprecation.warn("original_#{property} is deprecated. Define self.#{property} and call super instead.")
422
+ If you'd like the new behavior today, you can add this line:
359
423
 
360
- if !instance_variable_defined?("@original_#{property}") && respond_to?("reset_#{property}")
361
- send("reset_#{property}")
362
- else
363
- instance_variable_get("@original_#{property}")
424
+ attribute :#{column.name}, :point#{array_arguments}
425
+ WARNING
364
426
  end
365
427
  end
366
428
  end