activerecord 4.2.0 → 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 (249) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1537 -789
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -8
  5. data/examples/performance.rb +2 -3
  6. data/examples/simple.rb +0 -1
  7. data/lib/active_record/aggregations.rb +37 -23
  8. data/lib/active_record/association_relation.rb +16 -3
  9. data/lib/active_record/associations/alias_tracker.rb +19 -16
  10. data/lib/active_record/associations/association.rb +23 -9
  11. data/lib/active_record/associations/association_scope.rb +74 -102
  12. data/lib/active_record/associations/belongs_to_association.rb +26 -29
  13. data/lib/active_record/associations/builder/association.rb +28 -34
  14. data/lib/active_record/associations/builder/belongs_to.rb +43 -18
  15. data/lib/active_record/associations/builder/collection_association.rb +12 -20
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +22 -15
  17. data/lib/active_record/associations/builder/has_many.rb +4 -4
  18. data/lib/active_record/associations/builder/has_one.rb +11 -6
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -10
  20. data/lib/active_record/associations/collection_association.rb +61 -33
  21. data/lib/active_record/associations/collection_proxy.rb +81 -35
  22. data/lib/active_record/associations/foreign_association.rb +11 -0
  23. data/lib/active_record/associations/has_many_association.rb +21 -57
  24. data/lib/active_record/associations/has_many_through_association.rb +15 -45
  25. data/lib/active_record/associations/has_one_association.rb +13 -5
  26. data/lib/active_record/associations/join_dependency/join_association.rb +20 -8
  27. data/lib/active_record/associations/join_dependency.rb +37 -21
  28. data/lib/active_record/associations/preloader/association.rb +51 -53
  29. data/lib/active_record/associations/preloader/collection_association.rb +0 -6
  30. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  31. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  32. data/lib/active_record/associations/preloader/through_association.rb +27 -14
  33. data/lib/active_record/associations/preloader.rb +18 -8
  34. data/lib/active_record/associations/singular_association.rb +8 -8
  35. data/lib/active_record/associations/through_association.rb +22 -9
  36. data/lib/active_record/associations.rb +321 -212
  37. data/lib/active_record/attribute/user_provided_default.rb +28 -0
  38. data/lib/active_record/attribute.rb +79 -15
  39. data/lib/active_record/attribute_assignment.rb +20 -141
  40. data/lib/active_record/attribute_decorators.rb +6 -5
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +6 -1
  42. data/lib/active_record/attribute_methods/dirty.rb +51 -81
  43. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  44. data/lib/active_record/attribute_methods/query.rb +2 -2
  45. data/lib/active_record/attribute_methods/read.rb +31 -59
  46. data/lib/active_record/attribute_methods/serialization.rb +13 -16
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +65 -14
  48. data/lib/active_record/attribute_methods/write.rb +14 -38
  49. data/lib/active_record/attribute_methods.rb +70 -45
  50. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  51. data/lib/active_record/attribute_set/builder.rb +37 -15
  52. data/lib/active_record/attribute_set.rb +34 -3
  53. data/lib/active_record/attributes.rb +199 -73
  54. data/lib/active_record/autosave_association.rb +73 -25
  55. data/lib/active_record/base.rb +35 -27
  56. data/lib/active_record/callbacks.rb +39 -43
  57. data/lib/active_record/coders/json.rb +1 -1
  58. data/lib/active_record/coders/yaml_column.rb +20 -8
  59. data/lib/active_record/collection_cache_key.rb +40 -0
  60. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +457 -181
  61. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
  62. data/lib/active_record/connection_adapters/abstract/database_statements.rb +83 -59
  63. data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -3
  64. data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -9
  65. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -4
  66. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
  67. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +246 -185
  68. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
  69. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +438 -136
  70. data/lib/active_record/connection_adapters/abstract/transaction.rb +53 -40
  71. data/lib/active_record/connection_adapters/abstract_adapter.rb +166 -66
  72. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +429 -335
  73. data/lib/active_record/connection_adapters/column.rb +28 -43
  74. data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
  75. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  76. data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
  77. data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
  78. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
  79. data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
  80. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
  81. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
  82. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
  83. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
  84. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -177
  85. data/lib/active_record/connection_adapters/postgresql/column.rb +5 -10
  86. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +11 -73
  87. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +27 -56
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -13
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +3 -3
  95. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
  98. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
  99. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
  101. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +17 -5
  102. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
  103. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
  104. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
  106. data/lib/active_record/connection_adapters/postgresql/quoting.rb +26 -18
  107. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
  108. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
  109. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +248 -154
  111. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  112. data/lib/active_record/connection_adapters/postgresql_adapter.rb +258 -170
  113. data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
  114. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  115. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
  116. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
  117. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  118. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +150 -209
  119. data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
  120. data/lib/active_record/connection_handling.rb +38 -15
  121. data/lib/active_record/core.rb +109 -114
  122. data/lib/active_record/counter_cache.rb +14 -25
  123. data/lib/active_record/dynamic_matchers.rb +1 -20
  124. data/lib/active_record/enum.rb +115 -79
  125. data/lib/active_record/errors.rb +88 -48
  126. data/lib/active_record/explain_registry.rb +1 -1
  127. data/lib/active_record/explain_subscriber.rb +2 -2
  128. data/lib/active_record/fixture_set/file.rb +26 -5
  129. data/lib/active_record/fixtures.rb +84 -46
  130. data/lib/active_record/gem_version.rb +2 -2
  131. data/lib/active_record/inheritance.rb +32 -40
  132. data/lib/active_record/integration.rb +4 -4
  133. data/lib/active_record/internal_metadata.rb +56 -0
  134. data/lib/active_record/legacy_yaml_adapter.rb +46 -0
  135. data/lib/active_record/locale/en.yml +3 -2
  136. data/lib/active_record/locking/optimistic.rb +27 -25
  137. data/lib/active_record/locking/pessimistic.rb +1 -1
  138. data/lib/active_record/log_subscriber.rb +43 -21
  139. data/lib/active_record/migration/command_recorder.rb +59 -18
  140. data/lib/active_record/migration/compatibility.rb +126 -0
  141. data/lib/active_record/migration.rb +372 -114
  142. data/lib/active_record/model_schema.rb +128 -38
  143. data/lib/active_record/nested_attributes.rb +71 -32
  144. data/lib/active_record/no_touching.rb +1 -1
  145. data/lib/active_record/null_relation.rb +16 -8
  146. data/lib/active_record/persistence.rb +124 -80
  147. data/lib/active_record/query_cache.rb +15 -18
  148. data/lib/active_record/querying.rb +10 -9
  149. data/lib/active_record/railtie.rb +28 -19
  150. data/lib/active_record/railties/controller_runtime.rb +1 -1
  151. data/lib/active_record/railties/databases.rake +67 -51
  152. data/lib/active_record/readonly_attributes.rb +1 -1
  153. data/lib/active_record/reflection.rb +318 -139
  154. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  155. data/lib/active_record/relation/batches.rb +139 -34
  156. data/lib/active_record/relation/calculations.rb +80 -102
  157. data/lib/active_record/relation/delegation.rb +7 -20
  158. data/lib/active_record/relation/finder_methods.rb +167 -97
  159. data/lib/active_record/relation/from_clause.rb +32 -0
  160. data/lib/active_record/relation/merger.rb +38 -41
  161. data/lib/active_record/relation/predicate_builder/array_handler.rb +12 -16
  162. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
  163. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  164. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  165. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  166. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
  167. data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
  168. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  169. data/lib/active_record/relation/predicate_builder.rb +124 -82
  170. data/lib/active_record/relation/query_attribute.rb +19 -0
  171. data/lib/active_record/relation/query_methods.rb +323 -257
  172. data/lib/active_record/relation/record_fetch_warning.rb +49 -0
  173. data/lib/active_record/relation/spawn_methods.rb +11 -10
  174. data/lib/active_record/relation/where_clause.rb +174 -0
  175. data/lib/active_record/relation/where_clause_factory.rb +38 -0
  176. data/lib/active_record/relation.rb +176 -115
  177. data/lib/active_record/result.rb +4 -3
  178. data/lib/active_record/runtime_registry.rb +1 -1
  179. data/lib/active_record/sanitization.rb +95 -66
  180. data/lib/active_record/schema.rb +26 -22
  181. data/lib/active_record/schema_dumper.rb +62 -38
  182. data/lib/active_record/schema_migration.rb +11 -17
  183. data/lib/active_record/scoping/default.rb +24 -9
  184. data/lib/active_record/scoping/named.rb +49 -28
  185. data/lib/active_record/scoping.rb +32 -15
  186. data/lib/active_record/secure_token.rb +38 -0
  187. data/lib/active_record/serialization.rb +2 -4
  188. data/lib/active_record/statement_cache.rb +16 -14
  189. data/lib/active_record/store.rb +8 -3
  190. data/lib/active_record/suppressor.rb +58 -0
  191. data/lib/active_record/table_metadata.rb +68 -0
  192. data/lib/active_record/tasks/database_tasks.rb +59 -42
  193. data/lib/active_record/tasks/mysql_database_tasks.rb +32 -26
  194. data/lib/active_record/tasks/postgresql_database_tasks.rb +29 -9
  195. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  196. data/lib/active_record/timestamp.rb +20 -9
  197. data/lib/active_record/touch_later.rb +58 -0
  198. data/lib/active_record/transactions.rb +159 -67
  199. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  200. data/lib/active_record/type/date.rb +2 -41
  201. data/lib/active_record/type/date_time.rb +2 -38
  202. data/lib/active_record/type/hash_lookup_type_map.rb +8 -2
  203. data/lib/active_record/type/internal/abstract_json.rb +29 -0
  204. data/lib/active_record/type/internal/timezone.rb +15 -0
  205. data/lib/active_record/type/serialized.rb +21 -14
  206. data/lib/active_record/type/time.rb +10 -16
  207. data/lib/active_record/type/type_map.rb +4 -4
  208. data/lib/active_record/type.rb +66 -17
  209. data/lib/active_record/type_caster/connection.rb +29 -0
  210. data/lib/active_record/type_caster/map.rb +19 -0
  211. data/lib/active_record/type_caster.rb +7 -0
  212. data/lib/active_record/validations/absence.rb +23 -0
  213. data/lib/active_record/validations/associated.rb +10 -3
  214. data/lib/active_record/validations/length.rb +24 -0
  215. data/lib/active_record/validations/presence.rb +11 -12
  216. data/lib/active_record/validations/uniqueness.rb +29 -18
  217. data/lib/active_record/validations.rb +33 -32
  218. data/lib/active_record.rb +9 -2
  219. data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
  220. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -6
  221. data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -7
  222. data/lib/rails/generators/active_record/migration.rb +7 -0
  223. data/lib/rails/generators/active_record/model/model_generator.rb +32 -15
  224. data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
  225. data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
  226. metadata +60 -34
  227. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  228. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  229. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
  230. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  231. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  232. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  233. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  234. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  235. data/lib/active_record/type/big_integer.rb +0 -13
  236. data/lib/active_record/type/binary.rb +0 -50
  237. data/lib/active_record/type/boolean.rb +0 -30
  238. data/lib/active_record/type/decimal.rb +0 -40
  239. data/lib/active_record/type/decimal_without_scale.rb +0 -11
  240. data/lib/active_record/type/decorator.rb +0 -14
  241. data/lib/active_record/type/float.rb +0 -19
  242. data/lib/active_record/type/integer.rb +0 -55
  243. data/lib/active_record/type/mutable.rb +0 -16
  244. data/lib/active_record/type/numeric.rb +0 -36
  245. data/lib/active_record/type/string.rb +0 -36
  246. data/lib/active_record/type/text.rb +0 -11
  247. data/lib/active_record/type/time_value.rb +0 -38
  248. data/lib/active_record/type/unsigned_integer.rb +0 -15
  249. data/lib/active_record/type/value.rb +0 -101
@@ -1,6 +1,7 @@
1
1
  require 'erb'
2
2
  require 'yaml'
3
3
  require 'zlib'
4
+ require 'set'
4
5
  require 'active_support/dependencies'
5
6
  require 'active_support/core_ext/digest/uuid'
6
7
  require 'active_record/fixture_set/file'
@@ -88,7 +89,7 @@ module ActiveRecord
88
89
  # end
89
90
  #
90
91
  # In order to use these methods to access fixtured data within your testcases, you must specify one of the
91
- # following in your <tt>ActiveSupport::TestCase</tt>-derived class:
92
+ # following in your ActiveSupport::TestCase-derived class:
92
93
  #
93
94
  # - to fully enable instantiated fixtures (enable alternate methods #1 and #2 above)
94
95
  # self.use_instantiated_fixtures = true
@@ -109,7 +110,7 @@ module ActiveRecord
109
110
  # <% 1.upto(1000) do |i| %>
110
111
  # fix_<%= i %>:
111
112
  # id: <%= i %>
112
- # name: guy_<%= 1 %>
113
+ # name: guy_<%= i %>
113
114
  # <% end %>
114
115
  #
115
116
  # This will create 1000 very simple fixtures.
@@ -123,7 +124,7 @@ module ActiveRecord
123
124
  #
124
125
  # Helper methods defined in a fixture will not be available in other fixtures, to prevent against
125
126
  # unwanted inter-test dependencies. Methods used by multiple fixtures should be defined in a module
126
- # that is included in <tt>ActiveRecord::FixtureSet.context_class</tt>.
127
+ # that is included in ActiveRecord::FixtureSet.context_class.
127
128
  #
128
129
  # - define a helper method in `test_helper.rb`
129
130
  # module FixtureFileHelpers
@@ -131,20 +132,20 @@ module ActiveRecord
131
132
  # Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
132
133
  # end
133
134
  # end
134
- # ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers
135
+ # ActiveRecord::FixtureSet.context_class.include FixtureFileHelpers
135
136
  #
136
137
  # - use the helper method in a fixture
137
138
  # photo:
138
139
  # name: kitten.png
139
140
  # sha: <%= file_sha 'files/kitten.png' %>
140
141
  #
141
- # = Transactional Fixtures
142
+ # = Transactional Tests
142
143
  #
143
144
  # Test cases can use begin+rollback to isolate their changes to the database instead of having to
144
145
  # delete+insert for every test case.
145
146
  #
146
147
  # class FooTest < ActiveSupport::TestCase
147
- # self.use_transactional_fixtures = true
148
+ # self.use_transactional_tests = true
148
149
  #
149
150
  # test "godzilla" do
150
151
  # assert !Foo.all.empty?
@@ -158,14 +159,14 @@ module ActiveRecord
158
159
  # end
159
160
  #
160
161
  # If you preload your test database with all fixture data (probably in the rake task) and use
161
- # transactional fixtures, then you may omit all fixtures declarations in your test cases since
162
+ # transactional tests, then you may omit all fixtures declarations in your test cases since
162
163
  # all the data's already there and every case rolls back its changes.
163
164
  #
164
165
  # In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to
165
166
  # true. This will provide access to fixture data for every table that has been loaded through
166
167
  # fixtures (depending on the value of +use_instantiated_fixtures+).
167
168
  #
168
- # When *not* to use transactional fixtures:
169
+ # When *not* to use transactional tests:
169
170
  #
170
171
  # 1. You're testing whether a transaction works correctly. Nested transactions don't commit until
171
172
  # all parent transactions commit, particularly, the fixtures transaction which is begun in setup
@@ -394,6 +395,20 @@ module ActiveRecord
394
395
  # <<: *DEFAULTS
395
396
  #
396
397
  # Any fixture labeled "DEFAULTS" is safely ignored.
398
+ #
399
+ # == Configure the fixture model class
400
+ #
401
+ # It's possible to set the fixture's model class directly in the YAML file.
402
+ # This is helpful when fixtures are loaded outside tests and
403
+ # +set_fixture_class+ is not available (e.g.
404
+ # when running <tt>rails db:fixtures:load</tt>).
405
+ #
406
+ # _fixture:
407
+ # model_class: User
408
+ # david:
409
+ # name: David
410
+ #
411
+ # Any fixtures labeled "_fixture" are safely ignored.
397
412
  class FixtureSet
398
413
  #--
399
414
  # An instance of FixtureSet is normally stored in a single YAML file and
@@ -521,12 +536,16 @@ module ActiveRecord
521
536
  update_all_loaded_fixtures fixtures_map
522
537
 
523
538
  connection.transaction(:requires_new => true) do
539
+ deleted_tables = Set.new
524
540
  fixture_sets.each do |fs|
525
541
  conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection
526
542
  table_rows = fs.table_rows
527
543
 
528
544
  table_rows.each_key do |table|
529
- conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
545
+ unless deleted_tables.include? table
546
+ conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
547
+ end
548
+ deleted_tables << table
530
549
  end
531
550
 
532
551
  table_rows.each do |fixture_set_name, rows|
@@ -534,12 +553,10 @@ module ActiveRecord
534
553
  conn.insert_fixture(row, fixture_set_name)
535
554
  end
536
555
  end
537
- end
538
556
 
539
- # Cap primary key sequences to max(pk).
540
- if connection.respond_to?(:reset_pk_sequence!)
541
- fixture_sets.each do |fs|
542
- connection.reset_pk_sequence!(fs.table_name)
557
+ # Cap primary key sequences to max(pk).
558
+ if conn.respond_to?(:reset_pk_sequence!)
559
+ conn.reset_pk_sequence!(fs.table_name)
543
560
  end
544
561
  end
545
562
  end
@@ -575,21 +592,16 @@ module ActiveRecord
575
592
  @name = name
576
593
  @path = path
577
594
  @config = config
578
- @model_class = nil
579
595
 
580
- if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any?
581
- @model_class = class_name
582
- else
583
- @model_class = class_name.safe_constantize if class_name
584
- end
596
+ self.model_class = class_name
597
+
598
+ @fixtures = read_fixture_files(path)
585
599
 
586
600
  @connection = connection
587
601
 
588
602
  @table_name = ( model_class.respond_to?(:table_name) ?
589
603
  model_class.table_name :
590
604
  self.class.default_fixture_table_name(name, config) )
591
-
592
- @fixtures = read_fixture_files path, @model_class
593
605
  end
594
606
 
595
607
  def [](x)
@@ -612,7 +624,6 @@ module ActiveRecord
612
624
  # a list of rows to insert to that table.
613
625
  def table_rows
614
626
  now = config.default_timezone == :utc ? Time.now.utc : Time.now
615
- now = now.to_s(:db)
616
627
 
617
628
  # allow a standard key to be used for doing defaults in YAML
618
629
  fixtures.delete('DEFAULTS')
@@ -633,7 +644,7 @@ module ActiveRecord
633
644
 
634
645
  # interpolate the fixture label
635
646
  row.each do |key, value|
636
- row[key] = value.gsub("$LABEL", label) if value.is_a?(String)
647
+ row[key] = value.gsub("$LABEL", label.to_s) if value.is_a?(String)
637
648
  end
638
649
 
639
650
  # generate a primary key if necessary
@@ -641,6 +652,13 @@ module ActiveRecord
641
652
  row[primary_key_name] = ActiveRecord::FixtureSet.identify(label, primary_key_type)
642
653
  end
643
654
 
655
+ # Resolve enums
656
+ model_class.defined_enums.each do |name, values|
657
+ if row.include?(name)
658
+ row[name] = values.fetch(row[name], row[name])
659
+ end
660
+ end
661
+
644
662
  # If STI is used, find the correct subclass for association reflection
645
663
  reflection_class =
646
664
  if row.include?(inheritance_column_name)
@@ -661,7 +679,7 @@ module ActiveRecord
661
679
  row[association.foreign_type] = $1
662
680
  end
663
681
 
664
- fk_type = association.active_record.columns_hash[fk_name].type
682
+ fk_type = reflection_class.type_for_attribute(fk_name).type
665
683
  row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
666
684
  end
667
685
  when :has_many
@@ -691,7 +709,7 @@ module ActiveRecord
691
709
  end
692
710
 
693
711
  def primary_key_type
694
- @association.klass.column_types[@association.klass.primary_key].type
712
+ @association.klass.type_for_attribute(@association.klass.primary_key).type
695
713
  end
696
714
  end
697
715
 
@@ -703,6 +721,10 @@ module ActiveRecord
703
721
  def lhs_key
704
722
  @association.through_reflection.foreign_key
705
723
  end
724
+
725
+ def join_table
726
+ @association.through_reflection.table_name
727
+ end
706
728
  end
707
729
 
708
730
  private
@@ -711,7 +733,7 @@ module ActiveRecord
711
733
  end
712
734
 
713
735
  def primary_key_type
714
- @primary_key_type ||= model_class && model_class.column_types[model_class.primary_key].type
736
+ @primary_key_type ||= model_class && model_class.type_for_attribute(model_class.primary_key).type
715
737
  end
716
738
 
717
739
  def add_join_records(rows, row, association)
@@ -745,16 +767,28 @@ module ActiveRecord
745
767
  end
746
768
 
747
769
  def column_names
748
- @column_names ||= @connection.columns(@table_name).collect { |c| c.name }
770
+ @column_names ||= @connection.columns(@table_name).collect(&:name)
771
+ end
772
+
773
+ def model_class=(class_name)
774
+ if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any?
775
+ @model_class = class_name
776
+ else
777
+ @model_class = class_name.safe_constantize if class_name
778
+ end
749
779
  end
750
780
 
751
- def read_fixture_files(path, model_class)
781
+ # Loads the fixtures from the YAML file at +path+.
782
+ # If the file sets the +model_class+ and current instance value is not set,
783
+ # it uses the file value.
784
+ def read_fixture_files(path)
752
785
  yaml_files = Dir["#{path}/{**,*}/*.yml"].select { |f|
753
786
  ::File.file?(f)
754
787
  } + [yaml_file_path(path)]
755
788
 
756
789
  yaml_files.each_with_object({}) do |file, fixtures|
757
790
  FixtureSet::File.open(file) do |fh|
791
+ self.model_class ||= fh.model_class if fh.model_class
758
792
  fh.each do |fixture_name, row|
759
793
  fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
760
794
  end
@@ -768,12 +802,6 @@ module ActiveRecord
768
802
 
769
803
  end
770
804
 
771
- #--
772
- # Deprecate 'Fixtures' in favor of 'FixtureSet'.
773
- #++
774
- # :nodoc:
775
- Fixtures = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('ActiveRecord::Fixtures', 'ActiveRecord::FixtureSet')
776
-
777
805
  class Fixture #:nodoc:
778
806
  include Enumerable
779
807
 
@@ -820,12 +848,12 @@ module ActiveRecord
820
848
  module TestFixtures
821
849
  extend ActiveSupport::Concern
822
850
 
823
- def before_setup
851
+ def before_setup # :nodoc:
824
852
  setup_fixtures
825
853
  super
826
854
  end
827
855
 
828
- def after_teardown
856
+ def after_teardown # :nodoc:
829
857
  super
830
858
  teardown_fixtures
831
859
  end
@@ -834,19 +862,29 @@ module ActiveRecord
834
862
  class_attribute :fixture_path, :instance_writer => false
835
863
  class_attribute :fixture_table_names
836
864
  class_attribute :fixture_class_names
865
+ class_attribute :use_transactional_tests
837
866
  class_attribute :use_transactional_fixtures
838
867
  class_attribute :use_instantiated_fixtures # true, false, or :no_instances
839
868
  class_attribute :pre_loaded_fixtures
840
869
  class_attribute :config
841
870
 
871
+ singleton_class.deprecate 'use_transactional_fixtures=' => 'use use_transactional_tests= instead'
872
+
842
873
  self.fixture_table_names = []
843
- self.use_transactional_fixtures = true
844
874
  self.use_instantiated_fixtures = false
845
875
  self.pre_loaded_fixtures = false
846
876
  self.config = ActiveRecord::Base
847
877
 
848
- self.fixture_class_names = Hash.new do |h, fixture_set_name|
849
- h[fixture_set_name] = ActiveRecord::FixtureSet.default_fixture_model_name(fixture_set_name, self.config)
878
+ self.fixture_class_names = {}
879
+
880
+ silence_warnings do
881
+ define_singleton_method :use_transactional_tests do
882
+ if use_transactional_fixtures.nil?
883
+ true
884
+ else
885
+ use_transactional_fixtures
886
+ end
887
+ end
850
888
  end
851
889
  end
852
890
 
@@ -868,7 +906,7 @@ module ActiveRecord
868
906
  fixture_set_names = Dir["#{fixture_path}/{**,*}/*.{yml}"]
869
907
  fixture_set_names.map! { |f| f[(fixture_path.to_s.size + 1)..-5] }
870
908
  else
871
- fixture_set_names = fixture_set_names.flatten.map { |n| n.to_s }
909
+ fixture_set_names = fixture_set_names.flatten.map(&:to_s)
872
910
  end
873
911
 
874
912
  self.fixture_table_names |= fixture_set_names
@@ -888,7 +926,7 @@ module ActiveRecord
888
926
  @fixture_cache[fs_name] ||= {}
889
927
 
890
928
  instances = fixture_names.map do |f_name|
891
- f_name = f_name.to_s
929
+ f_name = f_name.to_s if f_name.is_a?(Symbol)
892
930
  @fixture_cache[fs_name].delete(f_name) if force_reload
893
931
 
894
932
  if @loaded_fixtures[fs_name][f_name]
@@ -908,7 +946,7 @@ module ActiveRecord
908
946
 
909
947
  def uses_transaction(*methods)
910
948
  @uses_transaction = [] unless defined?(@uses_transaction)
911
- @uses_transaction.concat methods.map { |m| m.to_s }
949
+ @uses_transaction.concat methods.map(&:to_s)
912
950
  end
913
951
 
914
952
  def uses_transaction?(method)
@@ -918,13 +956,13 @@ module ActiveRecord
918
956
  end
919
957
 
920
958
  def run_in_transaction?
921
- use_transactional_fixtures &&
959
+ use_transactional_tests &&
922
960
  !self.class.uses_transaction?(method_name)
923
961
  end
924
962
 
925
963
  def setup_fixtures(config = ActiveRecord::Base)
926
- if pre_loaded_fixtures && !use_transactional_fixtures
927
- raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
964
+ if pre_loaded_fixtures && !use_transactional_tests
965
+ raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_tests'
928
966
  end
929
967
 
930
968
  @fixture_cache = {}
@@ -5,8 +5,8 @@ module ActiveRecord
5
5
  end
6
6
 
7
7
  module VERSION
8
- MAJOR = 4
9
- MINOR = 2
8
+ MAJOR = 5
9
+ MINOR = 0
10
10
  TINY = 0
11
11
  PRE = nil
12
12
 
@@ -51,11 +51,15 @@ module ActiveRecord
51
51
  end
52
52
 
53
53
  attrs = args.first
54
- if subclass_from_attributes?(attrs)
54
+ if has_attribute?(inheritance_column)
55
55
  subclass = subclass_from_attributes(attrs)
56
+
57
+ if subclass.nil? && base_class == self
58
+ subclass = subclass_from_attributes(column_defaults)
59
+ end
56
60
  end
57
61
 
58
- if subclass
62
+ if subclass && subclass != self
59
63
  subclass.new(*args, &block)
60
64
  else
61
65
  super
@@ -79,20 +83,10 @@ module ActiveRecord
79
83
  :true == (@finder_needs_type_condition ||= descends_from_active_record? ? :false : :true)
80
84
  end
81
85
 
82
- def symbolized_base_class
83
- ActiveSupport::Deprecation.warn('`ActiveRecord::Base.symbolized_base_class` is deprecated and will be removed without replacement.')
84
- @symbolized_base_class ||= base_class.to_s.to_sym
85
- end
86
-
87
- def symbolized_sti_name
88
- ActiveSupport::Deprecation.warn('`ActiveRecord::Base.symbolized_sti_name` is deprecated and will be removed without replacement.')
89
- @symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class
90
- end
91
-
92
86
  # Returns the class descending directly from ActiveRecord::Base, or
93
87
  # an abstract class, if any, in the inheritance hierarchy.
94
88
  #
95
- # If A extends AR::Base, A.base_class will return A. If B descends from A
89
+ # If A extends ActiveRecord::Base, A.base_class will return A. If B descends from A
96
90
  # through some arbitrarily deep hierarchy, B.base_class will return A.
97
91
  #
98
92
  # If B < A and C < B and if A is an abstract_class then both B.base_class
@@ -173,49 +167,47 @@ module ActiveRecord
173
167
  end
174
168
 
175
169
  def using_single_table_inheritance?(record)
176
- record[inheritance_column].present? && columns_hash.include?(inheritance_column)
170
+ record[inheritance_column].present? && has_attribute?(inheritance_column)
177
171
  end
178
172
 
179
173
  def find_sti_class(type_name)
180
- if store_full_sti_class
181
- ActiveSupport::Dependencies.constantize(type_name)
182
- else
183
- compute_type(type_name)
174
+ type_name = base_class.type_for_attribute(inheritance_column).cast(type_name)
175
+ subclass = begin
176
+ if store_full_sti_class
177
+ ActiveSupport::Dependencies.constantize(type_name)
178
+ else
179
+ compute_type(type_name)
180
+ end
181
+ rescue NameError
182
+ raise SubclassNotFound,
183
+ "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
184
+ "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
185
+ "Please rename this column if you didn't intend it to be used for storing the inheritance class " \
186
+ "or overwrite #{name}.inheritance_column to use another column for that information."
184
187
  end
185
- rescue NameError
186
- raise SubclassNotFound,
187
- "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " +
188
- "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
189
- "Please rename this column if you didn't intend it to be used for storing the inheritance class " +
190
- "or overwrite #{name}.inheritance_column to use another column for that information."
188
+ unless subclass == self || descendants.include?(subclass)
189
+ raise SubclassNotFound, "Invalid single-table inheritance type: #{subclass.name} is not a subclass of #{name}"
190
+ end
191
+ subclass
191
192
  end
192
193
 
193
194
  def type_condition(table = arel_table)
194
- sti_column = table[inheritance_column]
195
- sti_names = ([self] + descendants).map { |model| model.sti_name }
195
+ sti_column = arel_attribute(inheritance_column, table)
196
+ sti_names = ([self] + descendants).map(&:sti_name)
196
197
 
197
198
  sti_column.in(sti_names)
198
199
  end
199
200
 
200
201
  # Detect the subclass from the inheritance column of attrs. If the inheritance column value
201
202
  # is not self or a valid subclass, raises ActiveRecord::SubclassNotFound
202
- # If this is a StrongParameters hash, and access to inheritance_column is not permitted,
203
- # this will ignore the inheritance column and return nil
204
- def subclass_from_attributes?(attrs)
205
- columns_hash.include?(inheritance_column) && attrs.is_a?(Hash)
206
- end
207
-
208
203
  def subclass_from_attributes(attrs)
209
- subclass_name = attrs.with_indifferent_access[inheritance_column]
210
-
211
- if subclass_name.present? && subclass_name != self.name
212
- subclass = subclass_name.safe_constantize
204
+ attrs = attrs.to_h if attrs.respond_to?(:permitted?)
205
+ if attrs.is_a?(Hash)
206
+ subclass_name = attrs.with_indifferent_access[inheritance_column]
213
207
 
214
- unless descendants.include?(subclass)
215
- raise ActiveRecord::SubclassNotFound.new("Invalid single-table inheritance type: #{subclass_name} is not a subclass of #{name}")
208
+ if subclass_name.present?
209
+ find_sti_class(subclass_name)
216
210
  end
217
-
218
- subclass
219
211
  end
220
212
  end
221
213
  end
@@ -10,12 +10,12 @@ module ActiveRecord
10
10
  # Indicates the format used to generate the timestamp in the cache key.
11
11
  # Accepts any of the symbols in <tt>Time::DATE_FORMATS</tt>.
12
12
  #
13
- # This is +:nsec+, by default.
13
+ # This is +:usec+, by default.
14
14
  class_attribute :cache_timestamp_format, :instance_writer => false
15
- self.cache_timestamp_format = :nsec
15
+ self.cache_timestamp_format = :usec
16
16
  end
17
17
 
18
- # Returns a String, which Action Pack uses for constructing an URL to this
18
+ # Returns a String, which Action Pack uses for constructing a URL to this
19
19
  # object. The default implementation returns this record's id as a String,
20
20
  # or nil if this record's unsaved.
21
21
  #
@@ -84,7 +84,7 @@ module ActiveRecord
84
84
  # Values longer than 20 characters will be truncated. The value
85
85
  # is truncated word by word.
86
86
  #
87
- # user = User.find_by(name: 'David HeinemeierHansson')
87
+ # user = User.find_by(name: 'David Heinemeier Hansson')
88
88
  # user.id # => 125
89
89
  # user_path(user) # => "/users/125-david"
90
90
  #
@@ -0,0 +1,56 @@
1
+ require 'active_record/scoping/default'
2
+ require 'active_record/scoping/named'
3
+
4
+ module ActiveRecord
5
+ # This class is used to create a table that keeps track of values and keys such
6
+ # as which environment migrations were run in.
7
+ class InternalMetadata < ActiveRecord::Base # :nodoc:
8
+ class << self
9
+ def primary_key
10
+ "key"
11
+ end
12
+
13
+ def table_name
14
+ "#{table_name_prefix}#{ActiveRecord::Base.internal_metadata_table_name}#{table_name_suffix}"
15
+ end
16
+
17
+ def original_table_name
18
+ "#{table_name_prefix}active_record_internal_metadatas#{table_name_suffix}"
19
+ end
20
+
21
+ def []=(key, value)
22
+ find_or_initialize_by(key: key).update_attributes!(value: value)
23
+ end
24
+
25
+ def [](key)
26
+ where(key: key).pluck(:value).first
27
+ end
28
+
29
+ def table_exists?
30
+ ActiveSupport::Deprecation.silence { connection.table_exists?(table_name) }
31
+ end
32
+
33
+ def original_table_exists?
34
+ # This method will be removed in Rails 5.1
35
+ # Since it is only necessary when `active_record_internal_metadatas` could exist
36
+ ActiveSupport::Deprecation.silence { connection.table_exists?(original_table_name) }
37
+ end
38
+
39
+ # Creates an internal metadata table with columns +key+ and +value+
40
+ def create_table
41
+ if original_table_exists?
42
+ connection.rename_table(original_table_name, table_name)
43
+ end
44
+ unless table_exists?
45
+ key_options = connection.internal_string_options_for_primary_key
46
+
47
+ connection.create_table(table_name, id: false) do |t|
48
+ t.string :key, key_options
49
+ t.string :value
50
+ t.timestamps
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,46 @@
1
+ module ActiveRecord
2
+ module LegacyYamlAdapter
3
+ def self.convert(klass, coder)
4
+ return coder unless coder.is_a?(Psych::Coder)
5
+
6
+ case coder["active_record_yaml_version"]
7
+ when 1 then coder
8
+ else
9
+ if coder["attributes"].is_a?(AttributeSet)
10
+ Rails420.convert(klass, coder)
11
+ else
12
+ Rails41.convert(klass, coder)
13
+ end
14
+ end
15
+ end
16
+
17
+ module Rails420
18
+ def self.convert(klass, coder)
19
+ attribute_set = coder["attributes"]
20
+
21
+ klass.attribute_names.each do |attr_name|
22
+ attribute = attribute_set[attr_name]
23
+ if attribute.type.is_a?(Delegator)
24
+ type_from_klass = klass.type_for_attribute(attr_name)
25
+ attribute_set[attr_name] = attribute.with_type(type_from_klass)
26
+ end
27
+ end
28
+
29
+ coder
30
+ end
31
+ end
32
+
33
+ module Rails41
34
+ def self.convert(klass, coder)
35
+ attributes = klass.attributes_builder
36
+ .build_from_database(coder["attributes"])
37
+ new_record = coder["attributes"][klass.primary_key].blank?
38
+
39
+ {
40
+ "attributes" => attributes,
41
+ "new_record" => new_record,
42
+ }
43
+ end
44
+ end
45
+ end
46
+ end
@@ -7,6 +7,7 @@ en:
7
7
  # Default error messages
8
8
  errors:
9
9
  messages:
10
+ required: "must exist"
10
11
  taken: "has already been taken"
11
12
 
12
13
  # Active Record models configuration
@@ -15,8 +16,8 @@ en:
15
16
  messages:
16
17
  record_invalid: "Validation failed: %{errors}"
17
18
  restrict_dependent_destroy:
18
- one: "Cannot delete record because a dependent %{record} exists"
19
- many: "Cannot delete record because dependent %{record} exist"
19
+ has_one: "Cannot delete record because a dependent %{record} exists"
20
+ has_many: "Cannot delete record because dependent %{record} exist"
20
21
  # Append your own errors here or at the model/attributes scope.
21
22
 
22
23
  # You can define own errors for models or model attributes.