activerecord 3.2.22.5 → 4.2.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (236) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1632 -609
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +37 -41
  5. data/examples/performance.rb +31 -19
  6. data/examples/simple.rb +4 -4
  7. data/lib/active_record/aggregations.rb +56 -42
  8. data/lib/active_record/association_relation.rb +35 -0
  9. data/lib/active_record/associations/alias_tracker.rb +47 -36
  10. data/lib/active_record/associations/association.rb +73 -55
  11. data/lib/active_record/associations/association_scope.rb +143 -82
  12. data/lib/active_record/associations/belongs_to_association.rb +65 -25
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -2
  14. data/lib/active_record/associations/builder/association.rb +125 -31
  15. data/lib/active_record/associations/builder/belongs_to.rb +89 -61
  16. data/lib/active_record/associations/builder/collection_association.rb +69 -49
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +113 -42
  18. data/lib/active_record/associations/builder/has_many.rb +8 -64
  19. data/lib/active_record/associations/builder/has_one.rb +12 -51
  20. data/lib/active_record/associations/builder/singular_association.rb +23 -17
  21. data/lib/active_record/associations/collection_association.rb +251 -177
  22. data/lib/active_record/associations/collection_proxy.rb +963 -63
  23. data/lib/active_record/associations/foreign_association.rb +11 -0
  24. data/lib/active_record/associations/has_many_association.rb +113 -22
  25. data/lib/active_record/associations/has_many_through_association.rb +99 -39
  26. data/lib/active_record/associations/has_one_association.rb +43 -20
  27. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  28. data/lib/active_record/associations/join_dependency/join_association.rb +76 -107
  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 +230 -156
  32. data/lib/active_record/associations/preloader/association.rb +96 -55
  33. data/lib/active_record/associations/preloader/collection_association.rb +3 -3
  34. data/lib/active_record/associations/preloader/has_many_through.rb +7 -3
  35. data/lib/active_record/associations/preloader/has_one.rb +1 -1
  36. data/lib/active_record/associations/preloader/singular_association.rb +3 -3
  37. data/lib/active_record/associations/preloader/through_association.rb +62 -33
  38. data/lib/active_record/associations/preloader.rb +101 -79
  39. data/lib/active_record/associations/singular_association.rb +29 -13
  40. data/lib/active_record/associations/through_association.rb +30 -16
  41. data/lib/active_record/associations.rb +463 -345
  42. data/lib/active_record/attribute.rb +163 -0
  43. data/lib/active_record/attribute_assignment.rb +142 -151
  44. data/lib/active_record/attribute_decorators.rb +66 -0
  45. data/lib/active_record/attribute_methods/before_type_cast.rb +52 -7
  46. data/lib/active_record/attribute_methods/dirty.rb +137 -57
  47. data/lib/active_record/attribute_methods/primary_key.rb +50 -36
  48. data/lib/active_record/attribute_methods/query.rb +5 -4
  49. data/lib/active_record/attribute_methods/read.rb +73 -106
  50. data/lib/active_record/attribute_methods/serialization.rb +44 -94
  51. data/lib/active_record/attribute_methods/time_zone_conversion.rb +49 -45
  52. data/lib/active_record/attribute_methods/write.rb +57 -44
  53. data/lib/active_record/attribute_methods.rb +301 -141
  54. data/lib/active_record/attribute_set/builder.rb +106 -0
  55. data/lib/active_record/attribute_set.rb +81 -0
  56. data/lib/active_record/attributes.rb +147 -0
  57. data/lib/active_record/autosave_association.rb +246 -217
  58. data/lib/active_record/base.rb +70 -474
  59. data/lib/active_record/callbacks.rb +66 -28
  60. data/lib/active_record/coders/json.rb +13 -0
  61. data/lib/active_record/coders/yaml_column.rb +18 -21
  62. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +396 -219
  63. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  64. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -164
  65. data/lib/active_record/connection_adapters/abstract/query_cache.rb +29 -24
  66. data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -55
  67. data/lib/active_record/connection_adapters/abstract/savepoints.rb +21 -0
  68. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +125 -0
  69. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +261 -169
  70. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +50 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +707 -259
  72. data/lib/active_record/connection_adapters/abstract/transaction.rb +215 -0
  73. data/lib/active_record/connection_adapters/abstract_adapter.rb +298 -89
  74. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +466 -196
  75. data/lib/active_record/connection_adapters/column.rb +31 -245
  76. data/lib/active_record/connection_adapters/connection_specification.rb +275 -0
  77. data/lib/active_record/connection_adapters/mysql2_adapter.rb +45 -57
  78. data/lib/active_record/connection_adapters/mysql_adapter.rb +180 -123
  79. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +93 -0
  80. data/lib/active_record/connection_adapters/postgresql/column.rb +20 -0
  81. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +232 -0
  82. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +100 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +52 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +13 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +15 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +46 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +11 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +13 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +19 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +21 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +59 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +13 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +13 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +11 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +35 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +23 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +43 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +43 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +79 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +19 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +11 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +109 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +21 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +26 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +28 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +36 -0
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +108 -0
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +152 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +596 -0
  112. data/lib/active_record/connection_adapters/postgresql/utils.rb +77 -0
  113. data/lib/active_record/connection_adapters/postgresql_adapter.rb +430 -999
  114. data/lib/active_record/connection_adapters/schema_cache.rb +52 -27
  115. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +579 -22
  116. data/lib/active_record/connection_handling.rb +132 -0
  117. data/lib/active_record/core.rb +579 -0
  118. data/lib/active_record/counter_cache.rb +157 -105
  119. data/lib/active_record/dynamic_matchers.rb +119 -63
  120. data/lib/active_record/enum.rb +197 -0
  121. data/lib/active_record/errors.rb +94 -36
  122. data/lib/active_record/explain.rb +15 -63
  123. data/lib/active_record/explain_registry.rb +30 -0
  124. data/lib/active_record/explain_subscriber.rb +9 -5
  125. data/lib/active_record/fixture_set/file.rb +56 -0
  126. data/lib/active_record/fixtures.rb +302 -215
  127. data/lib/active_record/gem_version.rb +15 -0
  128. data/lib/active_record/inheritance.rb +143 -70
  129. data/lib/active_record/integration.rb +65 -12
  130. data/lib/active_record/legacy_yaml_adapter.rb +30 -0
  131. data/lib/active_record/locale/en.yml +8 -1
  132. data/lib/active_record/locking/optimistic.rb +73 -52
  133. data/lib/active_record/locking/pessimistic.rb +5 -5
  134. data/lib/active_record/log_subscriber.rb +24 -21
  135. data/lib/active_record/migration/command_recorder.rb +124 -32
  136. data/lib/active_record/migration/join_table.rb +15 -0
  137. data/lib/active_record/migration.rb +511 -213
  138. data/lib/active_record/model_schema.rb +91 -117
  139. data/lib/active_record/nested_attributes.rb +184 -130
  140. data/lib/active_record/no_touching.rb +52 -0
  141. data/lib/active_record/null_relation.rb +81 -0
  142. data/lib/active_record/persistence.rb +276 -117
  143. data/lib/active_record/query_cache.rb +19 -37
  144. data/lib/active_record/querying.rb +28 -18
  145. data/lib/active_record/railtie.rb +73 -40
  146. data/lib/active_record/railties/console_sandbox.rb +3 -4
  147. data/lib/active_record/railties/controller_runtime.rb +4 -3
  148. data/lib/active_record/railties/databases.rake +141 -416
  149. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  150. data/lib/active_record/readonly_attributes.rb +1 -4
  151. data/lib/active_record/reflection.rb +513 -154
  152. data/lib/active_record/relation/batches.rb +91 -43
  153. data/lib/active_record/relation/calculations.rb +199 -161
  154. data/lib/active_record/relation/delegation.rb +116 -25
  155. data/lib/active_record/relation/finder_methods.rb +362 -248
  156. data/lib/active_record/relation/merger.rb +193 -0
  157. data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
  158. data/lib/active_record/relation/predicate_builder/relation_handler.rb +13 -0
  159. data/lib/active_record/relation/predicate_builder.rb +135 -43
  160. data/lib/active_record/relation/query_methods.rb +928 -167
  161. data/lib/active_record/relation/spawn_methods.rb +48 -149
  162. data/lib/active_record/relation.rb +352 -207
  163. data/lib/active_record/result.rb +101 -10
  164. data/lib/active_record/runtime_registry.rb +22 -0
  165. data/lib/active_record/sanitization.rb +56 -59
  166. data/lib/active_record/schema.rb +19 -13
  167. data/lib/active_record/schema_dumper.rb +106 -63
  168. data/lib/active_record/schema_migration.rb +53 -0
  169. data/lib/active_record/scoping/default.rb +50 -57
  170. data/lib/active_record/scoping/named.rb +73 -109
  171. data/lib/active_record/scoping.rb +58 -123
  172. data/lib/active_record/serialization.rb +6 -2
  173. data/lib/active_record/serializers/xml_serializer.rb +12 -22
  174. data/lib/active_record/statement_cache.rb +111 -0
  175. data/lib/active_record/store.rb +168 -15
  176. data/lib/active_record/tasks/database_tasks.rb +299 -0
  177. data/lib/active_record/tasks/mysql_database_tasks.rb +159 -0
  178. data/lib/active_record/tasks/postgresql_database_tasks.rb +101 -0
  179. data/lib/active_record/tasks/sqlite_database_tasks.rb +55 -0
  180. data/lib/active_record/timestamp.rb +23 -16
  181. data/lib/active_record/transactions.rb +125 -79
  182. data/lib/active_record/type/big_integer.rb +13 -0
  183. data/lib/active_record/type/binary.rb +50 -0
  184. data/lib/active_record/type/boolean.rb +31 -0
  185. data/lib/active_record/type/date.rb +50 -0
  186. data/lib/active_record/type/date_time.rb +54 -0
  187. data/lib/active_record/type/decimal.rb +64 -0
  188. data/lib/active_record/type/decimal_without_scale.rb +11 -0
  189. data/lib/active_record/type/decorator.rb +14 -0
  190. data/lib/active_record/type/float.rb +19 -0
  191. data/lib/active_record/type/hash_lookup_type_map.rb +23 -0
  192. data/lib/active_record/type/integer.rb +59 -0
  193. data/lib/active_record/type/mutable.rb +16 -0
  194. data/lib/active_record/type/numeric.rb +36 -0
  195. data/lib/active_record/type/serialized.rb +62 -0
  196. data/lib/active_record/type/string.rb +40 -0
  197. data/lib/active_record/type/text.rb +11 -0
  198. data/lib/active_record/type/time.rb +26 -0
  199. data/lib/active_record/type/time_value.rb +38 -0
  200. data/lib/active_record/type/type_map.rb +64 -0
  201. data/lib/active_record/type/unsigned_integer.rb +15 -0
  202. data/lib/active_record/type/value.rb +110 -0
  203. data/lib/active_record/type.rb +23 -0
  204. data/lib/active_record/validations/associated.rb +24 -16
  205. data/lib/active_record/validations/presence.rb +67 -0
  206. data/lib/active_record/validations/uniqueness.rb +123 -64
  207. data/lib/active_record/validations.rb +36 -29
  208. data/lib/active_record/version.rb +5 -7
  209. data/lib/active_record.rb +66 -46
  210. data/lib/rails/generators/active_record/migration/migration_generator.rb +53 -8
  211. data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +5 -1
  212. data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
  213. data/lib/rails/generators/active_record/migration.rb +11 -8
  214. data/lib/rails/generators/active_record/model/model_generator.rb +9 -4
  215. data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
  216. data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
  217. data/lib/rails/generators/active_record.rb +3 -11
  218. metadata +101 -45
  219. data/examples/associations.png +0 -0
  220. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  221. data/lib/active_record/associations/join_helper.rb +0 -55
  222. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  223. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  224. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
  225. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
  226. data/lib/active_record/dynamic_finder_match.rb +0 -68
  227. data/lib/active_record/dynamic_scope_match.rb +0 -23
  228. data/lib/active_record/fixtures/file.rb +0 -65
  229. data/lib/active_record/identity_map.rb +0 -162
  230. data/lib/active_record/observer.rb +0 -121
  231. data/lib/active_record/session_store.rb +0 -360
  232. data/lib/active_record/test_case.rb +0 -73
  233. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  234. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  235. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  236. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,36 +1,24 @@
1
1
  require 'erb'
2
-
3
- begin
4
- require 'psych'
5
- rescue LoadError
6
- end
7
-
8
2
  require 'yaml'
9
3
  require 'zlib'
10
4
  require 'active_support/dependencies'
11
- require 'active_support/core_ext/array/wrap'
12
- require 'active_support/core_ext/object/blank'
13
- require 'active_support/core_ext/logger'
14
- require 'active_support/ordered_hash'
15
- require 'active_record/fixtures/file'
5
+ require 'active_support/core_ext/digest/uuid'
6
+ require 'active_record/fixture_set/file'
7
+ require 'active_record/errors'
16
8
 
17
- if defined? ActiveRecord
9
+ module ActiveRecord
18
10
  class FixtureClassNotFound < ActiveRecord::ActiveRecordError #:nodoc:
19
11
  end
20
- else
21
- class FixtureClassNotFound < StandardError #:nodoc:
22
- end
23
- end
24
12
 
25
- module ActiveRecord
26
13
  # \Fixtures are a way of organizing data that you want to test against; in short, sample data.
27
14
  #
28
15
  # They are stored in YAML files, one file per model, which are placed in the directory
29
16
  # appointed by <tt>ActiveSupport::TestCase.fixture_path=(path)</tt> (this is automatically
30
17
  # configured for Rails, so you can just put your files in <tt><your-rails-app>/test/fixtures/</tt>).
31
- # The fixture file ends with the <tt>.yml</tt> file extension (Rails example:
32
- # <tt><your-rails-app>/test/fixtures/web_sites.yml</tt>). The format of a fixture file looks
33
- # like this:
18
+ # The fixture file ends with the +.yml+ file extension, for example:
19
+ # <tt><your-rails-app>/test/fixtures/web_sites.yml</tt>).
20
+ #
21
+ # The format of a fixture file looks like this:
34
22
  #
35
23
  # rubyonrails:
36
24
  # id: 1
@@ -46,7 +34,7 @@ module ActiveRecord
46
34
  # is followed by an indented list of key/value pairs in the "key: value" format. Records are
47
35
  # separated by a blank line for your viewing pleasure.
48
36
  #
49
- # Note that fixtures are unordered. If you want ordered fixtures, use the omap YAML type.
37
+ # Note: Fixtures are unordered. If you want ordered fixtures, use the omap YAML type.
50
38
  # See http://yaml.org/type/omap.html
51
39
  # for the specification. You will need ordered fixtures when you have foreign key constraints
52
40
  # on keys in the same table. This is commonly needed for tree structures. Example:
@@ -74,8 +62,8 @@ module ActiveRecord
74
62
  # end
75
63
  # end
76
64
  #
77
- # By default, <tt>test_helper.rb</tt> will load all of your fixtures into your test database,
78
- # so this test will succeed.
65
+ # By default, +test_helper.rb+ will load all of your fixtures into your test
66
+ # database, so this test will succeed.
79
67
  #
80
68
  # The testing environment will automatically load the all fixtures into the database before each
81
69
  # test. To ensure consistent data, the environment deletes the fixtures before running the load.
@@ -96,7 +84,7 @@ module ActiveRecord
96
84
  # end
97
85
  #
98
86
  # test "find_alt_method_2" do
99
- # assert_equal "Ruby on Rails", @rubyonrails.news
87
+ # assert_equal "Ruby on Rails", @rubyonrails.name
100
88
  # end
101
89
  #
102
90
  # In order to use these methods to access fixtured data within your testcases, you must specify one of the
@@ -133,6 +121,23 @@ module ActiveRecord
133
121
  # perhaps you should reexamine whether your application is properly testable. Hence, dynamic values
134
122
  # in fixtures are to be considered a code smell.
135
123
  #
124
+ # Helper methods defined in a fixture will not be available in other fixtures, to prevent against
125
+ # 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
+ #
128
+ # - define a helper method in `test_helper.rb`
129
+ # module FixtureFileHelpers
130
+ # def file_sha(path)
131
+ # Digest::SHA2.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
132
+ # end
133
+ # end
134
+ # ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers
135
+ #
136
+ # - use the helper method in a fixture
137
+ # photo:
138
+ # name: kitten.png
139
+ # sha: <%= file_sha 'files/kitten.png' %>
140
+ #
136
141
  # = Transactional Fixtures
137
142
  #
138
143
  # Test cases can use begin+rollback to isolate their changes to the database instead of having to
@@ -176,6 +181,9 @@ module ActiveRecord
176
181
  # * Stable, autogenerated IDs
177
182
  # * Label references for associations (belongs_to, has_one, has_many)
178
183
  # * HABTM associations as inline lists
184
+ #
185
+ # There are some more advanced features available even if the id is specified:
186
+ #
179
187
  # * Autofilled timestamp columns
180
188
  # * Fixture label interpolation
181
189
  # * Support for YAML defaults
@@ -262,7 +270,7 @@ module ActiveRecord
262
270
  #
263
271
  # ### in fruit.rb
264
272
  #
265
- # belongs_to :eater, :polymorphic => true
273
+ # belongs_to :eater, polymorphic: true
266
274
  #
267
275
  # ### in fruits.yml
268
276
  #
@@ -358,41 +366,54 @@ module ActiveRecord
358
366
  # geeksomnia:
359
367
  # name: Geeksomnia's Account
360
368
  # subdomain: $LABEL
369
+ # email: $LABEL@email.com
361
370
  #
362
371
  # Also, sometimes (like when porting older join table fixtures) you'll need
363
372
  # to be able to get a hold of the identifier for a given label. ERB
364
373
  # to the rescue:
365
374
  #
366
375
  # george_reginald:
367
- # monkey_id: <%= ActiveRecord::Fixtures.identify(:reginald) %>
368
- # pirate_id: <%= ActiveRecord::Fixtures.identify(:george) %>
376
+ # monkey_id: <%= ActiveRecord::FixtureSet.identify(:reginald) %>
377
+ # pirate_id: <%= ActiveRecord::FixtureSet.identify(:george) %>
369
378
  #
370
379
  # == Support for YAML defaults
371
380
  #
372
- # You probably already know how to use YAML to set and reuse defaults in
373
- # your <tt>database.yml</tt> file. You can use the same technique in your fixtures:
381
+ # You can set and reuse defaults in your fixtures YAML file.
382
+ # This is the same technique used in the +database.yml+ file to specify
383
+ # defaults:
374
384
  #
375
385
  # DEFAULTS: &DEFAULTS
376
386
  # created_on: <%= 3.weeks.ago.to_s(:db) %>
377
387
  #
378
388
  # first:
379
389
  # name: Smurf
380
- # *DEFAULTS
390
+ # <<: *DEFAULTS
381
391
  #
382
392
  # second:
383
393
  # name: Fraggle
384
- # *DEFAULTS
394
+ # <<: *DEFAULTS
385
395
  #
386
396
  # Any fixture labeled "DEFAULTS" is safely ignored.
387
- class Fixtures
397
+ class FixtureSet
398
+ #--
399
+ # An instance of FixtureSet is normally stored in a single YAML file and
400
+ # possibly in a folder with the same name.
401
+ #++
402
+
388
403
  MAX_ID = 2 ** 30 - 1
389
404
 
390
405
  @@all_cached_fixtures = Hash.new { |h,k| h[k] = {} }
391
406
 
392
- def self.find_table_name(table_name) # :nodoc:
393
- ActiveRecord::Base.pluralize_table_names ?
394
- table_name.to_s.singularize.camelize :
395
- table_name.to_s.camelize
407
+ def self.default_fixture_model_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc:
408
+ config.pluralize_table_names ?
409
+ fixture_set_name.singularize.camelize :
410
+ fixture_set_name.camelize
411
+ end
412
+
413
+ def self.default_fixture_table_name(fixture_set_name, config = ActiveRecord::Base) # :nodoc:
414
+ "#{ config.table_name_prefix }"\
415
+ "#{ fixture_set_name.tr('/', '_') }"\
416
+ "#{ config.table_name_suffix }".to_sym
396
417
  end
397
418
 
398
419
  def self.reset_cache
@@ -419,11 +440,7 @@ module ActiveRecord
419
440
  cache_for_connection(connection).update(fixtures_map)
420
441
  end
421
442
 
422
- #--
423
- # TODO:NOTE: in the next version, the __with_new_arity suffix and
424
- # the method with the old arity will be removed.
425
- #++
426
- def self.instantiate_fixtures__with_new_arity(object, fixture_set, load_instances = true) # :nodoc:
443
+ def self.instantiate_fixtures(object, fixture_set, load_instances = true)
427
444
  if load_instances
428
445
  fixture_set.each do |fixture_name, fixture|
429
446
  begin
@@ -435,79 +452,92 @@ module ActiveRecord
435
452
  end
436
453
  end
437
454
 
438
- # The use with parameters <tt>(object, fixture_set_name, fixture_set, load_instances = true)</tt> is deprecated, +fixture_set_name+ parameter is not used.
439
- # Use as:
440
- #
441
- # instantiate_fixtures(object, fixture_set, load_instances = true)
442
- def self.instantiate_fixtures(object, fixture_set, load_instances = true, rails_3_2_compatibility_argument = true)
443
- unless load_instances == true || load_instances == false
444
- ActiveSupport::Deprecation.warn(
445
- "ActiveRecord::Fixtures.instantiate_fixtures with parameters (object, fixture_set_name, fixture_set, load_instances = true) is deprecated and shall be removed from future releases. Use it with parameters (object, fixture_set, load_instances = true) instead (skip fixture_set_name).",
446
- caller)
447
- fixture_set = load_instances
448
- load_instances = rails_3_2_compatibility_argument
449
- end
450
- instantiate_fixtures__with_new_arity(object, fixture_set, load_instances)
451
- end
452
-
453
455
  def self.instantiate_all_loaded_fixtures(object, load_instances = true)
454
456
  all_loaded_fixtures.each_value do |fixture_set|
455
- ActiveRecord::Fixtures.instantiate_fixtures(object, fixture_set, load_instances)
457
+ instantiate_fixtures(object, fixture_set, load_instances)
456
458
  end
457
459
  end
458
460
 
459
461
  cattr_accessor :all_loaded_fixtures
460
462
  self.all_loaded_fixtures = {}
461
463
 
462
- def self.create_fixtures(fixtures_directory, table_names, class_names = {})
463
- table_names = [table_names].flatten.map { |n| n.to_s }
464
- table_names.each { |n|
465
- class_names[n.tr('/', '_').to_sym] = n.classify if n.include?('/')
466
- }
464
+ class ClassCache
465
+ def initialize(class_names, config)
466
+ @class_names = class_names.stringify_keys
467
+ @config = config
468
+
469
+ # Remove string values that aren't constants or subclasses of AR
470
+ @class_names.delete_if { |klass_name, klass| !insert_class(@class_names, klass_name, klass) }
471
+ end
472
+
473
+ def [](fs_name)
474
+ @class_names.fetch(fs_name) {
475
+ klass = default_fixture_model(fs_name, @config).safe_constantize
476
+ insert_class(@class_names, fs_name, klass)
477
+ }
478
+ end
479
+
480
+ private
481
+
482
+ def insert_class(class_names, name, klass)
483
+ # We only want to deal with AR objects.
484
+ if klass && klass < ActiveRecord::Base
485
+ class_names[name] = klass
486
+ else
487
+ class_names[name] = nil
488
+ end
489
+ end
490
+
491
+ def default_fixture_model(fs_name, config)
492
+ ActiveRecord::FixtureSet.default_fixture_model_name(fs_name, config)
493
+ end
494
+ end
495
+
496
+ def self.create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base)
497
+ fixture_set_names = Array(fixture_set_names).map(&:to_s)
498
+ class_names = ClassCache.new class_names, config
467
499
 
468
500
  # FIXME: Apparently JK uses this.
469
501
  connection = block_given? ? yield : ActiveRecord::Base.connection
470
502
 
471
- files_to_read = table_names.reject { |table_name|
472
- fixture_is_cached?(connection, table_name)
503
+ files_to_read = fixture_set_names.reject { |fs_name|
504
+ fixture_is_cached?(connection, fs_name)
473
505
  }
474
506
 
475
507
  unless files_to_read.empty?
476
508
  connection.disable_referential_integrity do
477
509
  fixtures_map = {}
478
510
 
479
- fixture_files = files_to_read.map do |path|
480
- table_name = path.tr '/', '_'
481
-
482
- fixtures_map[path] = ActiveRecord::Fixtures.new(
483
- connection,
484
- table_name,
485
- class_names[table_name.to_sym] || table_name.classify,
486
- ::File.join(fixtures_directory, path))
511
+ fixture_sets = files_to_read.map do |fs_name|
512
+ klass = class_names[fs_name]
513
+ conn = klass ? klass.connection : connection
514
+ fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new
515
+ conn,
516
+ fs_name,
517
+ klass,
518
+ ::File.join(fixtures_directory, fs_name))
487
519
  end
488
520
 
489
- all_loaded_fixtures.update(fixtures_map)
521
+ update_all_loaded_fixtures fixtures_map
490
522
 
491
523
  connection.transaction(:requires_new => true) do
492
- fixture_files.each do |ff|
493
- conn = ff.model_class.respond_to?(:connection) ? ff.model_class.connection : connection
494
- table_rows = ff.table_rows
524
+ fixture_sets.each do |fs|
525
+ conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection
526
+ table_rows = fs.table_rows
495
527
 
496
- table_rows.keys.each do |table|
528
+ table_rows.each_key do |table|
497
529
  conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
498
530
  end
499
531
 
500
- table_rows.each do |table_name,rows|
532
+ table_rows.each do |fixture_set_name, rows|
501
533
  rows.each do |row|
502
- conn.insert_fixture(row, table_name)
534
+ conn.insert_fixture(row, fixture_set_name)
503
535
  end
504
536
  end
505
- end
506
537
 
507
- # Cap primary key sequences to max(pk).
508
- if connection.respond_to?(:reset_pk_sequence!)
509
- table_names.each do |table_name|
510
- connection.reset_pk_sequence!(table_name.tr('/', '_'))
538
+ # Cap primary key sequences to max(pk).
539
+ if conn.respond_to?(:reset_pk_sequence!)
540
+ conn.reset_pk_sequence!(fs.table_name)
511
541
  end
512
542
  end
513
543
  end
@@ -515,37 +545,49 @@ module ActiveRecord
515
545
  cache_fixtures(connection, fixtures_map)
516
546
  end
517
547
  end
518
- cached_fixtures(connection, table_names)
548
+ cached_fixtures(connection, fixture_set_names)
519
549
  end
520
550
 
521
551
  # Returns a consistent, platform-independent identifier for +label+.
522
- # Identifiers are positive integers less than 2^32.
523
- def self.identify(label)
524
- Zlib.crc32(label.to_s) % MAX_ID
552
+ # Integer identifiers are values less than 2^30. UUIDs are RFC 4122 version 5 SHA-1 hashes.
553
+ def self.identify(label, column_type = :integer)
554
+ if column_type == :uuid
555
+ Digest::UUID.uuid_v5(Digest::UUID::OID_NAMESPACE, label.to_s)
556
+ else
557
+ Zlib.crc32(label.to_s) % MAX_ID
558
+ end
525
559
  end
526
560
 
527
- attr_reader :table_name, :name, :fixtures, :model_class
561
+ # Superclass for the evaluation contexts used by ERB fixtures.
562
+ def self.context_class
563
+ @context_class ||= Class.new
564
+ end
565
+
566
+ def self.update_all_loaded_fixtures(fixtures_map) # :nodoc:
567
+ all_loaded_fixtures.update(fixtures_map)
568
+ end
528
569
 
529
- def initialize(connection, table_name, class_name, fixture_path)
530
- @connection = connection
531
- @table_name = table_name
532
- @fixture_path = fixture_path
533
- @name = table_name # preserve fixture base name
534
- @class_name = class_name
570
+ attr_reader :table_name, :name, :fixtures, :model_class, :config
535
571
 
536
- @fixtures = ActiveSupport::OrderedHash.new
537
- @table_name = "#{ActiveRecord::Base.table_name_prefix}#{@table_name}#{ActiveRecord::Base.table_name_suffix}"
572
+ def initialize(connection, name, class_name, path, config = ActiveRecord::Base)
573
+ @name = name
574
+ @path = path
575
+ @config = config
576
+ @model_class = nil
538
577
 
539
- # Should be an AR::Base type class
540
- if class_name.is_a?(Class)
541
- @table_name = class_name.table_name
542
- @connection = class_name.connection
543
- @model_class = class_name
578
+ if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any?
579
+ @model_class = class_name
544
580
  else
545
- @model_class = class_name.constantize rescue nil
581
+ @model_class = class_name.safe_constantize if class_name
546
582
  end
547
583
 
548
- read_fixture_files
584
+ @connection = connection
585
+
586
+ @table_name = ( model_class.respond_to?(:table_name) ?
587
+ model_class.table_name :
588
+ self.class.default_fixture_table_name(name, config) )
589
+
590
+ @fixtures = read_fixture_files path, @model_class
549
591
  end
550
592
 
551
593
  def [](x)
@@ -564,10 +606,10 @@ module ActiveRecord
564
606
  fixtures.size
565
607
  end
566
608
 
567
- # Return a hash of rows to be inserted. The key is the table, the value is
609
+ # Returns a hash of rows to be inserted. The key is the table, the value is
568
610
  # a list of rows to insert to that table.
569
611
  def table_rows
570
- now = ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
612
+ now = config.default_timezone == :utc ? Time.now.utc : Time.now
571
613
  now = now.to_s(:db)
572
614
 
573
615
  # allow a standard key to be used for doing defaults in YAML
@@ -579,22 +621,22 @@ module ActiveRecord
579
621
  rows[table_name] = fixtures.map do |label, fixture|
580
622
  row = fixture.to_hash
581
623
 
582
- if model_class && model_class < ActiveRecord::Base
624
+ if model_class
583
625
  # fill in timestamp columns if they aren't specified and the model is set to record_timestamps
584
626
  if model_class.record_timestamps
585
- timestamp_column_names.each do |name|
586
- row[name] = now unless row.key?(name)
627
+ timestamp_column_names.each do |c_name|
628
+ row[c_name] = now unless row.key?(c_name)
587
629
  end
588
630
  end
589
631
 
590
632
  # interpolate the fixture label
591
633
  row.each do |key, value|
592
- row[key] = label if value.is_a?(String) && value == "$LABEL"
634
+ row[key] = value.gsub("$LABEL", label.to_s) if value.is_a?(String)
593
635
  end
594
636
 
595
637
  # generate a primary key if necessary
596
638
  if has_primary_key_column? && !row.include?(primary_key_name)
597
- row[primary_key_name] = ActiveRecord::Fixtures.identify(label)
639
+ row[primary_key_name] = ActiveRecord::FixtureSet.identify(label, primary_key_type)
598
640
  end
599
641
 
600
642
  # If STI is used, find the correct subclass for association reflection
@@ -605,28 +647,24 @@ module ActiveRecord
605
647
  model_class
606
648
  end
607
649
 
608
- reflection_class.reflect_on_all_associations.each do |association|
650
+ reflection_class._reflections.each_value do |association|
609
651
  case association.macro
610
652
  when :belongs_to
611
653
  # Do not replace association name with association foreign key if they are named the same
612
654
  fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s
613
655
 
614
656
  if association.name.to_s != fk_name && value = row.delete(association.name.to_s)
615
- if association.options[:polymorphic] && value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
657
+ if association.polymorphic? && value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
616
658
  # support polymorphic belongs_to as "label (Type)"
617
659
  row[association.foreign_type] = $1
618
660
  end
619
661
 
620
- row[fk_name] = ActiveRecord::Fixtures.identify(value)
662
+ fk_type = reflection_class.columns_hash[fk_name].type
663
+ row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
621
664
  end
622
- when :has_and_belongs_to_many
623
- if (targets = row.delete(association.name.to_s))
624
- targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/)
625
- table_name = association.options[:join_table]
626
- rows[table_name].concat targets.map { |target|
627
- { association.foreign_key => row[primary_key_name],
628
- association.association_foreign_key => ActiveRecord::Fixtures.identify(target) }
629
- }
665
+ when :has_many
666
+ if association.options[:through]
667
+ add_join_records(rows, row, HasManyThroughProxy.new(association))
630
668
  end
631
669
  end
632
670
  end
@@ -637,11 +675,63 @@ module ActiveRecord
637
675
  rows
638
676
  end
639
677
 
678
+ class ReflectionProxy # :nodoc:
679
+ def initialize(association)
680
+ @association = association
681
+ end
682
+
683
+ def join_table
684
+ @association.join_table
685
+ end
686
+
687
+ def name
688
+ @association.name
689
+ end
690
+
691
+ def primary_key_type
692
+ @association.klass.column_types[@association.klass.primary_key].type
693
+ end
694
+ end
695
+
696
+ class HasManyThroughProxy < ReflectionProxy # :nodoc:
697
+ def rhs_key
698
+ @association.foreign_key
699
+ end
700
+
701
+ def lhs_key
702
+ @association.through_reflection.foreign_key
703
+ end
704
+
705
+ def join_table
706
+ @association.through_reflection.table_name
707
+ end
708
+ end
709
+
640
710
  private
641
711
  def primary_key_name
642
712
  @primary_key_name ||= model_class && model_class.primary_key
643
713
  end
644
714
 
715
+ def primary_key_type
716
+ @primary_key_type ||= model_class && model_class.column_types[model_class.primary_key].type
717
+ end
718
+
719
+ def add_join_records(rows, row, association)
720
+ # This is the case when the join table has no fixtures file
721
+ if (targets = row.delete(association.name.to_s))
722
+ table_name = association.join_table
723
+ column_type = association.primary_key_type
724
+ lhs_key = association.lhs_key
725
+ rhs_key = association.rhs_key
726
+
727
+ targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/)
728
+ rows[table_name].concat targets.map { |target|
729
+ { lhs_key => row[primary_key_name],
730
+ rhs_key => ActiveRecord::FixtureSet.identify(target, column_type) }
731
+ }
732
+ end
733
+ end
734
+
645
735
  def has_primary_key_column?
646
736
  @has_primary_key_column ||= primary_key_name &&
647
737
  model_class.columns.any? { |c| c.name == primary_key_name }
@@ -660,26 +750,32 @@ module ActiveRecord
660
750
  @column_names ||= @connection.columns(@table_name).collect { |c| c.name }
661
751
  end
662
752
 
663
- def read_fixture_files
664
- yaml_files = Dir["#{@fixture_path}/{**,*}/*.yml"].select { |f|
753
+ def read_fixture_files(path, model_class)
754
+ yaml_files = Dir["#{path}/{**,*}/*.yml"].select { |f|
665
755
  ::File.file?(f)
666
- } + [yaml_file_path]
756
+ } + [yaml_file_path(path)]
667
757
 
668
- yaml_files.each do |file|
669
- Fixtures::File.open(file) do |fh|
670
- fh.each do |name, row|
671
- fixtures[name] = ActiveRecord::Fixture.new(row, model_class)
758
+ yaml_files.each_with_object({}) do |file, fixtures|
759
+ FixtureSet::File.open(file) do |fh|
760
+ fh.each do |fixture_name, row|
761
+ fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
672
762
  end
673
763
  end
674
764
  end
675
765
  end
676
766
 
677
- def yaml_file_path
678
- "#{@fixture_path}.yml"
767
+ def yaml_file_path(path)
768
+ "#{path}.yml"
679
769
  end
680
770
 
681
771
  end
682
772
 
773
+ #--
774
+ # Deprecate 'Fixtures' in favor of 'FixtureSet'.
775
+ #++
776
+ # :nodoc:
777
+ Fixtures = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('ActiveRecord::Fixtures', 'ActiveRecord::FixtureSet')
778
+
683
779
  class Fixture #:nodoc:
684
780
  include Enumerable
685
781
 
@@ -712,7 +808,9 @@ module ActiveRecord
712
808
 
713
809
  def find
714
810
  if model_class
715
- model_class.find(fixture[model_class.primary_key])
811
+ model_class.unscoped do
812
+ model_class.find(fixture[model_class.primary_key])
813
+ end
716
814
  else
717
815
  raise FixtureClassNotFound, "No class attached to find."
718
816
  end
@@ -724,91 +822,87 @@ module ActiveRecord
724
822
  module TestFixtures
725
823
  extend ActiveSupport::Concern
726
824
 
727
- included do
728
- setup :setup_fixtures
729
- teardown :teardown_fixtures
825
+ def before_setup
826
+ setup_fixtures
827
+ super
828
+ end
730
829
 
731
- class_attribute :fixture_path
830
+ def after_teardown
831
+ super
832
+ teardown_fixtures
833
+ end
834
+
835
+ included do
836
+ class_attribute :fixture_path, :instance_writer => false
732
837
  class_attribute :fixture_table_names
733
838
  class_attribute :fixture_class_names
734
839
  class_attribute :use_transactional_fixtures
735
- class_attribute :use_instantiated_fixtures # true, false, or :no_instances
840
+ class_attribute :use_instantiated_fixtures # true, false, or :no_instances
736
841
  class_attribute :pre_loaded_fixtures
842
+ class_attribute :config
737
843
 
738
844
  self.fixture_table_names = []
739
845
  self.use_transactional_fixtures = true
740
846
  self.use_instantiated_fixtures = false
741
847
  self.pre_loaded_fixtures = false
848
+ self.config = ActiveRecord::Base
742
849
 
743
- self.fixture_class_names = Hash.new do |h, table_name|
744
- h[table_name] = ActiveRecord::Fixtures.find_table_name(table_name)
850
+ self.fixture_class_names = Hash.new do |h, fixture_set_name|
851
+ h[fixture_set_name] = ActiveRecord::FixtureSet.default_fixture_model_name(fixture_set_name, self.config)
745
852
  end
746
853
  end
747
854
 
748
855
  module ClassMethods
856
+ # Sets the model class for a fixture when the class name cannot be inferred from the fixture name.
857
+ #
858
+ # Examples:
859
+ #
860
+ # set_fixture_class some_fixture: SomeModel,
861
+ # 'namespaced/fixture' => Another::Model
862
+ #
863
+ # The keys must be the fixture names, that coincide with the short paths to the fixture files.
749
864
  def set_fixture_class(class_names = {})
750
- self.fixture_class_names = self.fixture_class_names.merge(class_names)
865
+ self.fixture_class_names = self.fixture_class_names.merge(class_names.stringify_keys)
751
866
  end
752
867
 
753
- def fixtures(*fixture_names)
754
- if fixture_names.first == :all
755
- fixture_names = Dir["#{fixture_path}/{**,*}/*.{yml}"]
756
- fixture_names.map! { |f| f[(fixture_path.size + 1)..-5] }
868
+ def fixtures(*fixture_set_names)
869
+ if fixture_set_names.first == :all
870
+ fixture_set_names = Dir["#{fixture_path}/{**,*}/*.{yml}"]
871
+ fixture_set_names.map! { |f| f[(fixture_path.to_s.size + 1)..-5] }
757
872
  else
758
- fixture_names = fixture_names.flatten.map { |n| n.to_s }
759
- end
760
-
761
- self.fixture_table_names |= fixture_names
762
- require_fixture_classes(fixture_names)
763
- setup_fixture_accessors(fixture_names)
764
- end
765
-
766
- def try_to_load_dependency(file_name)
767
- require_dependency file_name
768
- rescue LoadError => e
769
- # Let's hope the developer has included it himself
770
-
771
- # Let's warn in case this is a subdependency, otherwise
772
- # subdependency error messages are totally cryptic
773
- if ActiveRecord::Base.logger
774
- ActiveRecord::Base.logger.warn("Unable to load #{file_name}, underlying cause #{e.message} \n\n #{e.backtrace.join("\n")}")
873
+ fixture_set_names = fixture_set_names.flatten.map { |n| n.to_s }
775
874
  end
776
- end
777
875
 
778
- def require_fixture_classes(fixture_names = nil)
779
- (fixture_names || fixture_table_names).each do |fixture_name|
780
- file_name = fixture_name.to_s
781
- file_name = file_name.singularize if ActiveRecord::Base.pluralize_table_names
782
- try_to_load_dependency(file_name)
783
- end
876
+ self.fixture_table_names |= fixture_set_names
877
+ setup_fixture_accessors(fixture_set_names)
784
878
  end
785
879
 
786
- def setup_fixture_accessors(fixture_names = nil)
787
- fixture_names = Array.wrap(fixture_names || fixture_table_names)
880
+ def setup_fixture_accessors(fixture_set_names = nil)
881
+ fixture_set_names = Array(fixture_set_names || fixture_table_names)
788
882
  methods = Module.new do
789
- fixture_names.each do |fixture_name|
790
- fixture_name = fixture_name.to_s.tr('./', '_')
883
+ fixture_set_names.each do |fs_name|
884
+ fs_name = fs_name.to_s
885
+ accessor_name = fs_name.tr('/', '_').to_sym
791
886
 
792
- define_method(fixture_name) do |*fixtures|
793
- force_reload = fixtures.pop if fixtures.last == true || fixtures.last == :reload
887
+ define_method(accessor_name) do |*fixture_names|
888
+ force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
794
889
 
795
- @fixture_cache[fixture_name] ||= {}
890
+ @fixture_cache[fs_name] ||= {}
796
891
 
797
- instances = fixtures.map do |fixture|
798
- @fixture_cache[fixture_name].delete(fixture) if force_reload
892
+ instances = fixture_names.map do |f_name|
893
+ f_name = f_name.to_s
894
+ @fixture_cache[fs_name].delete(f_name) if force_reload
799
895
 
800
- if @loaded_fixtures[fixture_name][fixture.to_s]
801
- ActiveRecord::IdentityMap.without do
802
- @fixture_cache[fixture_name][fixture] ||= @loaded_fixtures[fixture_name][fixture.to_s].find
803
- end
896
+ if @loaded_fixtures[fs_name][f_name]
897
+ @fixture_cache[fs_name][f_name] ||= @loaded_fixtures[fs_name][f_name].find
804
898
  else
805
- raise StandardError, "No fixture with name '#{fixture}' found for table '#{fixture_name}'"
899
+ raise StandardError, "No fixture named '#{f_name}' found for fixture set '#{fs_name}'"
806
900
  end
807
901
  end
808
902
 
809
903
  instances.size == 1 ? instances.first : instances
810
904
  end
811
- private fixture_name
905
+ private accessor_name
812
906
  end
813
907
  end
814
908
  include methods
@@ -830,9 +924,7 @@ module ActiveRecord
830
924
  !self.class.uses_transaction?(method_name)
831
925
  end
832
926
 
833
- def setup_fixtures
834
- return unless !ActiveRecord::Base.configurations.blank?
835
-
927
+ def setup_fixtures(config = ActiveRecord::Base)
836
928
  if pre_loaded_fixtures && !use_transactional_fixtures
837
929
  raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
838
930
  end
@@ -846,20 +938,18 @@ module ActiveRecord
846
938
  if @@already_loaded_fixtures[self.class]
847
939
  @loaded_fixtures = @@already_loaded_fixtures[self.class]
848
940
  else
849
- @loaded_fixtures = load_fixtures
941
+ @loaded_fixtures = load_fixtures(config)
850
942
  @@already_loaded_fixtures[self.class] = @loaded_fixtures
851
943
  end
852
944
  @fixture_connections = enlist_fixture_connections
853
945
  @fixture_connections.each do |connection|
854
- connection.increment_open_transactions
855
- connection.transaction_joinable = false
856
- connection.begin_db_transaction
946
+ connection.begin_transaction joinable: false
857
947
  end
858
948
  # Load fixtures for every test.
859
949
  else
860
- ActiveRecord::Fixtures.reset_cache
950
+ ActiveRecord::FixtureSet.reset_cache
861
951
  @@already_loaded_fixtures[self.class] = nil
862
- @loaded_fixtures = load_fixtures
952
+ @loaded_fixtures = load_fixtures(config)
863
953
  end
864
954
 
865
955
  # Instantiate fixtures for every test if requested.
@@ -867,50 +957,37 @@ module ActiveRecord
867
957
  end
868
958
 
869
959
  def teardown_fixtures
870
- return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
871
-
872
- unless run_in_transaction?
873
- ActiveRecord::Fixtures.reset_cache
874
- end
875
-
876
960
  # Rollback changes if a transaction is active.
877
961
  if run_in_transaction?
878
962
  @fixture_connections.each do |connection|
879
- if connection.open_transactions != 0
880
- connection.rollback_db_transaction
881
- connection.decrement_open_transactions
882
- end
963
+ connection.rollback_transaction if connection.transaction_open?
883
964
  end
884
965
  @fixture_connections.clear
966
+ else
967
+ ActiveRecord::FixtureSet.reset_cache
885
968
  end
969
+
886
970
  ActiveRecord::Base.clear_active_connections!
887
971
  end
888
972
 
889
973
  def enlist_fixture_connections
890
- ActiveRecord::Base.connection_handler.connection_pools.values.map(&:connection)
974
+ ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection)
891
975
  end
892
976
 
893
977
  private
894
- def load_fixtures
895
- fixtures = ActiveRecord::Fixtures.create_fixtures(fixture_path, fixture_table_names, fixture_class_names)
978
+ def load_fixtures(config)
979
+ fixtures = ActiveRecord::FixtureSet.create_fixtures(fixture_path, fixture_table_names, fixture_class_names, config)
896
980
  Hash[fixtures.map { |f| [f.name, f] }]
897
981
  end
898
982
 
899
- # for pre_loaded_fixtures, only require the classes once. huge speed improvement
900
- @@required_fixture_classes = false
901
-
902
983
  def instantiate_fixtures
903
984
  if pre_loaded_fixtures
904
- raise RuntimeError, 'Load fixtures before instantiating them.' if ActiveRecord::Fixtures.all_loaded_fixtures.empty?
905
- unless @@required_fixture_classes
906
- self.class.require_fixture_classes ActiveRecord::Fixtures.all_loaded_fixtures.keys
907
- @@required_fixture_classes = true
908
- end
909
- ActiveRecord::Fixtures.instantiate_all_loaded_fixtures(self, load_instances?)
985
+ raise RuntimeError, 'Load fixtures before instantiating them.' if ActiveRecord::FixtureSet.all_loaded_fixtures.empty?
986
+ ActiveRecord::FixtureSet.instantiate_all_loaded_fixtures(self, load_instances?)
910
987
  else
911
988
  raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
912
989
  @loaded_fixtures.each_value do |fixture_set|
913
- ActiveRecord::Fixtures.instantiate_fixtures(self, fixture_set, load_instances?)
990
+ ActiveRecord::FixtureSet.instantiate_fixtures(self, fixture_set, load_instances?)
914
991
  end
915
992
  end
916
993
  end
@@ -920,3 +997,13 @@ module ActiveRecord
920
997
  end
921
998
  end
922
999
  end
1000
+
1001
+ class ActiveRecord::FixtureSet::RenderContext # :nodoc:
1002
+ def self.create_subclass
1003
+ Class.new ActiveRecord::FixtureSet.context_class do
1004
+ def get_binding
1005
+ binding()
1006
+ end
1007
+ end
1008
+ end
1009
+ end