tiny-lite-mod 0.0.1

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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/factory_bot-6.6.0/CONTRIBUTING.md +105 -0
  3. data/factory_bot-6.6.0/GETTING_STARTED.md +2203 -0
  4. data/factory_bot-6.6.0/LICENSE +19 -0
  5. data/factory_bot-6.6.0/NAME.md +18 -0
  6. data/factory_bot-6.6.0/NEWS.md +607 -0
  7. data/factory_bot-6.6.0/README.md +99 -0
  8. data/factory_bot-6.6.0/lib/factory_bot/aliases.rb +18 -0
  9. data/factory_bot-6.6.0/lib/factory_bot/attribute/association.rb +27 -0
  10. data/factory_bot-6.6.0/lib/factory_bot/attribute/dynamic.rb +25 -0
  11. data/factory_bot-6.6.0/lib/factory_bot/attribute/sequence.rb +16 -0
  12. data/factory_bot-6.6.0/lib/factory_bot/attribute.rb +27 -0
  13. data/factory_bot-6.6.0/lib/factory_bot/attribute_assigner.rb +168 -0
  14. data/factory_bot-6.6.0/lib/factory_bot/attribute_list.rb +68 -0
  15. data/factory_bot-6.6.0/lib/factory_bot/callback.rb +33 -0
  16. data/factory_bot-6.6.0/lib/factory_bot/callbacks_observer.rb +39 -0
  17. data/factory_bot-6.6.0/lib/factory_bot/configuration.rb +33 -0
  18. data/factory_bot-6.6.0/lib/factory_bot/declaration/association.rb +58 -0
  19. data/factory_bot-6.6.0/lib/factory_bot/declaration/dynamic.rb +28 -0
  20. data/factory_bot-6.6.0/lib/factory_bot/declaration/implicit.rb +38 -0
  21. data/factory_bot-6.6.0/lib/factory_bot/declaration.rb +23 -0
  22. data/factory_bot-6.6.0/lib/factory_bot/declaration_list.rb +49 -0
  23. data/factory_bot-6.6.0/lib/factory_bot/decorator/attribute_hash.rb +16 -0
  24. data/factory_bot-6.6.0/lib/factory_bot/decorator/disallows_duplicates_registry.rb +13 -0
  25. data/factory_bot-6.6.0/lib/factory_bot/decorator/invocation_tracker.rb +20 -0
  26. data/factory_bot-6.6.0/lib/factory_bot/decorator/new_constructor.rb +12 -0
  27. data/factory_bot-6.6.0/lib/factory_bot/decorator.rb +25 -0
  28. data/factory_bot-6.6.0/lib/factory_bot/definition.rb +210 -0
  29. data/factory_bot-6.6.0/lib/factory_bot/definition_hierarchy.rb +38 -0
  30. data/factory_bot-6.6.0/lib/factory_bot/definition_proxy.rb +269 -0
  31. data/factory_bot-6.6.0/lib/factory_bot/enum.rb +27 -0
  32. data/factory_bot-6.6.0/lib/factory_bot/errors.rb +28 -0
  33. data/factory_bot-6.6.0/lib/factory_bot/evaluation.rb +23 -0
  34. data/factory_bot-6.6.0/lib/factory_bot/evaluator.rb +86 -0
  35. data/factory_bot-6.6.0/lib/factory_bot/evaluator_class_definer.rb +20 -0
  36. data/factory_bot-6.6.0/lib/factory_bot/factory.rb +178 -0
  37. data/factory_bot-6.6.0/lib/factory_bot/factory_runner.rb +35 -0
  38. data/factory_bot-6.6.0/lib/factory_bot/find_definitions.rb +25 -0
  39. data/factory_bot-6.6.0/lib/factory_bot/internal.rb +124 -0
  40. data/factory_bot-6.6.0/lib/factory_bot/linter.rb +121 -0
  41. data/factory_bot-6.6.0/lib/factory_bot/null_factory.rb +27 -0
  42. data/factory_bot-6.6.0/lib/factory_bot/null_object.rb +20 -0
  43. data/factory_bot-6.6.0/lib/factory_bot/registry.rb +59 -0
  44. data/factory_bot-6.6.0/lib/factory_bot/reload.rb +7 -0
  45. data/factory_bot-6.6.0/lib/factory_bot/sequence.rb +197 -0
  46. data/factory_bot-6.6.0/lib/factory_bot/strategy/attributes_for.rb +17 -0
  47. data/factory_bot-6.6.0/lib/factory_bot/strategy/build.rb +21 -0
  48. data/factory_bot-6.6.0/lib/factory_bot/strategy/create.rb +24 -0
  49. data/factory_bot-6.6.0/lib/factory_bot/strategy/null.rb +15 -0
  50. data/factory_bot-6.6.0/lib/factory_bot/strategy/stub.rb +129 -0
  51. data/factory_bot-6.6.0/lib/factory_bot/strategy.rb +15 -0
  52. data/factory_bot-6.6.0/lib/factory_bot/strategy_syntax_method_registrar.rb +65 -0
  53. data/factory_bot-6.6.0/lib/factory_bot/syntax/default.rb +64 -0
  54. data/factory_bot-6.6.0/lib/factory_bot/syntax/methods.rb +181 -0
  55. data/factory_bot-6.6.0/lib/factory_bot/syntax.rb +7 -0
  56. data/factory_bot-6.6.0/lib/factory_bot/syntax_runner.rb +6 -0
  57. data/factory_bot-6.6.0/lib/factory_bot/trait.rb +39 -0
  58. data/factory_bot-6.6.0/lib/factory_bot/uri_manager.rb +63 -0
  59. data/factory_bot-6.6.0/lib/factory_bot/version.rb +3 -0
  60. data/factory_bot-6.6.0/lib/factory_bot.rb +117 -0
  61. data/tiny-lite-mod.gemspec +12 -0
  62. metadata +101 -0
@@ -0,0 +1,2203 @@
1
+ **Deprecated**
2
+
3
+ See our extensive reference, guides, and cookbook in [the factory_bot book][].
4
+
5
+ For information on integrations with third party libraries, such as RSpec or
6
+ Rails, see [the factory_bot wiki][].
7
+
8
+ We also have [a detailed introductory video][], available for free on Upcase.
9
+
10
+ [a detailed introductory video]: https://upcase.com/videos/factory-bot?utm_source=github&utm_medium=open-source&utm_campaign=factory-girl
11
+ [the factory_bot book]: https://thoughtbot.github.io/factory_bot
12
+ [the factory_bot wiki]: https://github.com/thoughtbot/factory_bot/wiki
13
+
14
+ This document is deprecated and preserved for historical use. It may disappear
15
+ at any time.
16
+
17
+ Getting Started
18
+ ===============
19
+
20
+ - [Setup](#setup)
21
+ - [Update Your Gemfile](#update-your-gemfile)
22
+ - [Configure your test suite](#configure-your-test-suite)
23
+ - [RSpec](#rspec)
24
+ - [Test::Unit](#testunit)
25
+ - [Cucumber](#cucumber)
26
+ - [Spinach](#spinach)
27
+ - [Minitest](#minitest)
28
+ - [Minitest::Spec](#minitestspec)
29
+ - [minitest-rails](#minitest-rails)
30
+ - [Defining factories](#defining-factories)
31
+ - [Factory name and attributes](#factory-name-and-attributes)
32
+ - [Specifying the class explicitly](#specifying-the-class-explicitly)
33
+ - [Hash attributes](#hash-attributes)
34
+ - [Best practices](#best-practices)
35
+ - [Definition file paths](#definition-file-paths)
36
+ - [Static Attributes](#static-attributes)
37
+ - [Using factories](#using-factories)
38
+ - [Build strategies](#build-strategies)
39
+ - [Attribute overrides](#attribute-overrides)
40
+ - [build\_stubbed and Marshal.dump](#build_stubbed-and-marshaldump)
41
+ - [Aliases](#aliases)
42
+ - [Dependent Attributes](#dependent-attributes)
43
+ - [Transient Attributes](#transient-attributes)
44
+ - [With other attributes](#with-other-attributes)
45
+ - [With attributes\_for](#with-attributes_for)
46
+ - [With callbacks](#with-callbacks)
47
+ - [With associations](#with-associations)
48
+ - [Method Name / Reserved Word Attributes](#method-name--reserved-word-attributes)
49
+ - [Inheritance](#inheritance)
50
+ - [Nested factories](#nested-factories)
51
+ - [Assigning parent explicitly](#assigning-parent-explicitly)
52
+ - [Best practices](#best-practices-1)
53
+ - [Associations](#associations)
54
+ - [Implicit definition](#implicit-definition)
55
+ - [Explicit definition](#explicit-definition)
56
+ - [Inline definition](#inline-definition)
57
+ - [Specifying the factory](#specifying-the-factory)
58
+ - [Overriding attributes](#overriding-attributes)
59
+ - [Association overrides](#association-overrides)
60
+ - [Build strategies](#build-strategies-1)
61
+ - [has\_many associations](#has_many-associations)
62
+ - [has\_and\_belongs\_to\_many associations](#has_and_belongs_to_many-associations)
63
+ - [Polymorphic associations](#polymorphic-associations)
64
+ - [Interconnected associations](#interconnected-associations)
65
+ - [Sequences](#sequences)
66
+ - [Global sequences](#global-sequences)
67
+ - [With dynamic attributes](#with-dynamic-attributes)
68
+ - [As implicit attributes](#as-implicit-attributes)
69
+ - [Inline sequences](#inline-sequences)
70
+ - [Initial value](#initial-value)
71
+ - [Without a block](#without-a-block)
72
+ - [Aliases](#aliases-1)
73
+ - [Rewinding](#rewinding)
74
+ - [Uniqueness](#uniqueness)
75
+ - [Traits](#traits)
76
+ - [Defining traits](#defining-traits)
77
+ - [As implicit attributes](#as-implicit-attributes-1)
78
+ - [Attribute precedence](#attribute-precedence)
79
+ - [In child factories](#in-child-factories)
80
+ - [As mixins](#as-mixins)
81
+ - [Using traits](#using-traits)
82
+ - [With associations](#with-associations-1)
83
+ - [Traits within traits](#traits-within-traits)
84
+ - [With transient attributes](#with-transient-attributes)
85
+ - [Enum traits](#enum-traits)
86
+ - [Callbacks](#callbacks)
87
+ - [Default callbacks](#default-callbacks)
88
+ - [Multiple callbacks](#multiple-callbacks)
89
+ - [Global callbacks](#global-callbacks)
90
+ - [Symbol#to\_proc](#symbolto_proc)
91
+ - [Modifying factories](#modifying-factories)
92
+ - [Building or Creating Multiple Records](#building-or-creating-multiple-records)
93
+ - [Linting Factories](#linting-factories)
94
+ - [Custom Construction](#custom-construction)
95
+ - [Custom Strategies](#custom-strategies)
96
+ - [Custom Callbacks](#custom-callbacks)
97
+ - [Custom Methods to Persist Objects](#custom-methods-to-persist-objects)
98
+ - [ActiveSupport Instrumentation](#activesupport-instrumentation)
99
+ - [Rails Preloaders and RSpec](#rails-preloaders-and-rspec)
100
+ - [Using Without Bundler](#using-without-bundler)
101
+
102
+ Setup
103
+ -----
104
+
105
+ ### Update Your Gemfile
106
+
107
+ If you're using Rails:
108
+
109
+ ```ruby
110
+ gem "factory_bot_rails"
111
+ ```
112
+
113
+ If you're *not* using Rails:
114
+
115
+ ```ruby
116
+ gem "factory_bot"
117
+ ```
118
+
119
+ ### Configure your test suite
120
+
121
+ #### RSpec
122
+
123
+ If you're using Rails, add the following configuration to
124
+ `spec/support/factory_bot.rb` and be sure to require that file in
125
+ `rails_helper.rb`:
126
+
127
+ ```ruby
128
+ RSpec.configure do |config|
129
+ config.include FactoryBot::Syntax::Methods
130
+ end
131
+ ```
132
+
133
+ If you're *not* using Rails:
134
+
135
+ ```ruby
136
+ RSpec.configure do |config|
137
+ config.include FactoryBot::Syntax::Methods
138
+
139
+ config.before(:suite) do
140
+ FactoryBot.find_definitions
141
+ end
142
+ end
143
+ ```
144
+
145
+ #### Test::Unit
146
+
147
+ ```ruby
148
+ class Test::Unit::TestCase
149
+ include FactoryBot::Syntax::Methods
150
+ end
151
+ ```
152
+
153
+ #### Cucumber
154
+
155
+ ```ruby
156
+ # env.rb (Rails example location - RAILS_ROOT/features/support/env.rb)
157
+ World(FactoryBot::Syntax::Methods)
158
+ ```
159
+
160
+ #### Spinach
161
+
162
+ ```ruby
163
+ class Spinach::FeatureSteps
164
+ include FactoryBot::Syntax::Methods
165
+ end
166
+ ```
167
+
168
+ #### Minitest
169
+
170
+ ```ruby
171
+ class Minitest::Unit::TestCase
172
+ include FactoryBot::Syntax::Methods
173
+ end
174
+ ```
175
+
176
+ #### Minitest::Spec
177
+
178
+ ```ruby
179
+ class Minitest::Spec
180
+ include FactoryBot::Syntax::Methods
181
+ end
182
+ ```
183
+
184
+ #### minitest-rails
185
+
186
+ ```ruby
187
+ class ActiveSupport::TestCase
188
+ include FactoryBot::Syntax::Methods
189
+ end
190
+ ```
191
+
192
+ If you do not include `FactoryBot::Syntax::Methods` in your test suite, then all
193
+ factory\_bot methods will need to be prefaced with `FactoryBot`.
194
+
195
+ Defining factories
196
+ ------------------
197
+
198
+ ### Factory name and attributes
199
+
200
+ Each factory has a name and a set of attributes. The name is used to guess the
201
+ class of the object by default:
202
+
203
+ ```ruby
204
+ # This will guess the User class
205
+ FactoryBot.define do
206
+ factory :user do
207
+ first_name { "John" }
208
+ last_name { "Doe" }
209
+ admin { false }
210
+ end
211
+ end
212
+ ```
213
+
214
+ ### Specifying the class explicitly
215
+
216
+ It is also possible to explicitly specify the class:
217
+
218
+ ```ruby
219
+ # This will use the User class (otherwise Admin would have been guessed)
220
+ factory :admin, class: "User"
221
+ ```
222
+
223
+ Explicit specification of the class, _with the full namespace_, is necessary when defining factories for classes nested within other modules or classes:
224
+
225
+ ```ruby
226
+ # foo/bar.rb
227
+ module Foo
228
+ class Bar
229
+ ...
230
+ end
231
+ end
232
+
233
+ # factories.rb
234
+ FactoryBot.define do
235
+ factory :bar, class: 'Foo::Bar' do
236
+ ...
237
+ end
238
+ end
239
+ ```
240
+
241
+ If the full namespace is not provided in the `factory` statement, you will receive a `NameError: uninitialized constant Bar` error.
242
+
243
+ You can pass a constant as well, if the constant is available (note that this
244
+ can cause test performance problems in large Rails applications, since
245
+ referring to the constant will cause it to be eagerly loaded).
246
+
247
+ ```ruby
248
+ factory :access_token, class: User
249
+ ```
250
+
251
+ ### Hash attributes
252
+
253
+ Because of the block syntax in Ruby, defining attributes as `Hash`es (for
254
+ serialized/JSON columns, for example) requires two sets of curly brackets:
255
+
256
+ ```ruby
257
+ factory :program do
258
+ configuration { { auto_resolve: false, auto_define: true } }
259
+ end
260
+ ```
261
+
262
+ ### Best practices
263
+
264
+ It is recommended that you have one factory for each class that provides
265
+ the simplest set of attributes necessary to create an instance of that class. If
266
+ you're creating ActiveRecord objects, that means that you should only provide
267
+ attributes that are required through validations and that do not have defaults.
268
+ Other factories can be created through inheritance to cover common scenarios for
269
+ each class.
270
+
271
+ Attempting to define multiple factories with the same name will raise an error.
272
+
273
+ ### Definition file paths
274
+
275
+ Factories can be defined anywhere, but will be automatically loaded after
276
+ calling `FactoryBot.find_definitions` if factories are defined in files at the
277
+ following locations:
278
+
279
+ factories.rb
280
+ factories/**/*.rb
281
+ test/factories.rb
282
+ test/factories/**/*.rb
283
+ spec/factories.rb
284
+ spec/factories/**/*.rb
285
+
286
+ ### Static Attributes
287
+
288
+ Static attributes (without a block) are no longer available in factory\_bot 5.
289
+ You can read more about the decision to remove them in
290
+ [this blog post](https://robots.thoughtbot.com/deprecating-static-attributes-in-factory_bot-4-11).
291
+
292
+
293
+ Using factories
294
+ ---------------
295
+
296
+ ### Build strategies
297
+
298
+ factory\_bot supports several different build strategies: build, create,
299
+ attributes\_for and build\_stubbed:
300
+
301
+ ```ruby
302
+ # Returns a User instance that's not saved
303
+ user = build(:user)
304
+
305
+ # Returns a saved User instance
306
+ user = create(:user)
307
+
308
+ # Returns a hash of attributes that can be used to build a User instance
309
+ attrs = attributes_for(:user)
310
+
311
+ # Integrates with Ruby 3.0's support for pattern matching assignment
312
+ attributes_for(:user) => {email:, name:, **attrs}
313
+
314
+ # Returns an object with all defined attributes stubbed out
315
+ stub = build_stubbed(:user)
316
+
317
+ # Passing a block to any of the methods above will yield the return object
318
+ create(:user) do |user|
319
+ user.posts.create(attributes_for(:post))
320
+ end
321
+ ```
322
+
323
+ ### Attribute overrides
324
+
325
+ No matter which strategy is used, it's possible to override the defined
326
+ attributes by passing a Hash:
327
+
328
+ ```ruby
329
+ # Build a User instance and override the first_name property
330
+ user = build(:user, first_name: "Joe")
331
+ user.first_name
332
+ # => "Joe"
333
+ ```
334
+
335
+ Overriding associations is also supported:
336
+
337
+ ```ruby
338
+ account = build(:account, :deluxe)
339
+ friends = build_list(:user, 2)
340
+
341
+ user = build(:user, account: account, friends: friends)
342
+ ```
343
+
344
+ Ruby 3.1's support for [omitting values][] from `Hash` literals dovetails with
345
+ attribute overrides and provides an opportunity to limit the repetition of
346
+ variable names:
347
+
348
+ ```ruby
349
+ account = build(:account, :deluxe)
350
+ friends = build_list(:user, 2)
351
+
352
+ # The keyword arguments correspond to local variable names, so omit their values
353
+ user = build(:user, account:, friends:)
354
+ ```
355
+
356
+ [omitting values]: https://docs.ruby-lang.org/en/3.1/syntax/literals_rdoc.html#label-Hash+Literals
357
+
358
+ ### build_stubbed and Marshal.dump
359
+
360
+ Note that objects created with `build_stubbed` cannot be serialized with
361
+ `Marshal.dump`, since factory\_bot defines singleton methods on these objects.
362
+
363
+ Aliases
364
+ -------
365
+
366
+ factory\_bot allows you to define aliases to existing factories to make them
367
+ easier to re-use. This could come in handy when, for example, your Post object
368
+ has an author attribute that actually refers to an instance of a User class.
369
+ While normally factory\_bot can infer the factory name from the association name,
370
+ in this case it will look for an author factory in vain. So, alias your user
371
+ factory so it can be used under alias names.
372
+
373
+ ```ruby
374
+ factory :user, aliases: [:author, :commenter] do
375
+ first_name { "John" }
376
+ last_name { "Doe" }
377
+ date_of_birth { 18.years.ago }
378
+ end
379
+
380
+ factory :post do
381
+ # The alias allows us to write author instead of
382
+ # association :author, factory: :user
383
+ author
384
+ title { "How to read a book effectively" }
385
+ body { "There are five steps involved." }
386
+ end
387
+
388
+ factory :comment do
389
+ # The alias allows us to write commenter instead of
390
+ # association :commenter, factory: :user
391
+ commenter
392
+ body { "Great article!" }
393
+ end
394
+ ```
395
+
396
+ Dependent Attributes
397
+ --------------------
398
+
399
+ Attributes can be based on the values of other attributes using the evaluator
400
+ that is yielded to dynamic attribute blocks:
401
+
402
+ ```ruby
403
+ factory :user do
404
+ first_name { "Joe" }
405
+ last_name { "Blow" }
406
+ email { "#{first_name}.#{last_name}@example.com".downcase }
407
+ end
408
+
409
+ create(:user, last_name: "Doe").email
410
+ # => "joe.doe@example.com"
411
+ ```
412
+
413
+ Transient Attributes
414
+ --------------------
415
+ Transient attributes are attributes only available within the factory definition, and not set on the object being built. This allows for more complex logic inside factories.
416
+
417
+ ### With other attributes
418
+
419
+ There may be times where your code can be DRYed up by passing in transient
420
+ attributes to factories. You can access transient attributes within other
421
+ attributes (see [Dependent Attributes](#dependent-attributes)):
422
+
423
+ ```ruby
424
+ factory :user do
425
+ transient do
426
+ rockstar { true }
427
+ end
428
+
429
+ name { "John Doe#{" - Rockstar" if rockstar}" }
430
+ end
431
+
432
+ create(:user).name
433
+ #=> "John Doe - ROCKSTAR"
434
+
435
+ create(:user, rockstar: false).name
436
+ #=> "John Doe"
437
+ ```
438
+
439
+ ### With attributes_for
440
+
441
+ Transient attributes will be ignored within attributes\_for and won't be set on
442
+ the model, even if the attribute exists or you attempt to override it.
443
+
444
+ ### With callbacks
445
+
446
+ If you need to access the evaluator in a factory\_bot callback,
447
+ you'll need to declare a second block argument (for the evaluator) and access
448
+ transient attributes from there.
449
+
450
+ ```ruby
451
+ factory :user do
452
+ transient do
453
+ upcased { false }
454
+ end
455
+
456
+ name { "John Doe" }
457
+
458
+ after(:create) do |user, evaluator|
459
+ user.name.upcase! if evaluator.upcased
460
+ end
461
+ end
462
+
463
+ create(:user).name
464
+ #=> "John Doe"
465
+
466
+ create(:user, upcased: true).name
467
+ #=> "JOHN DOE"
468
+ ```
469
+
470
+ ### With associations
471
+
472
+ Transient [associations](#associations) are not supported in factory\_bot.
473
+ Associations within the transient block will be treated as regular,
474
+ non-transient associations.
475
+
476
+ If needed, you can generally work around this by building a factory within a
477
+ transient attribute:
478
+
479
+ ```ruby
480
+ factory :post
481
+
482
+ factory :user do
483
+ transient do
484
+ post { build(:post) }
485
+ end
486
+ end
487
+ ```
488
+
489
+ Method Name / Reserved Word Attributes
490
+ -------------------------------
491
+
492
+ If your attributes conflict with existing methods or reserved words (all methods in the [DefinitionProxy](https://github.com/thoughtbot/factory_bot/blob/main/lib/factory_bot/definition_proxy.rb) class) you can define them with `add_attribute`.
493
+
494
+ ```ruby
495
+ factory :dna do
496
+ add_attribute(:sequence) { 'GATTACA' }
497
+ end
498
+
499
+ factory :payment do
500
+ add_attribute(:method) { 'paypal' }
501
+ end
502
+
503
+ ```
504
+
505
+ Inheritance
506
+ -----------
507
+
508
+ ### Nested factories
509
+
510
+ You can easily create multiple factories for the same class without repeating
511
+ common attributes by nesting factories:
512
+
513
+ ```ruby
514
+ factory :post do
515
+ title { "A title" }
516
+
517
+ factory :approved_post do
518
+ approved { true }
519
+ end
520
+ end
521
+
522
+ approved_post = create(:approved_post)
523
+ approved_post.title # => "A title"
524
+ approved_post.approved # => true
525
+ ```
526
+
527
+ ### Assigning parent explicitly
528
+
529
+ You can also assign the parent explicitly:
530
+
531
+ ```ruby
532
+ factory :post do
533
+ title { "A title" }
534
+ end
535
+
536
+ factory :approved_post, parent: :post do
537
+ approved { true }
538
+ end
539
+ ```
540
+
541
+ ### Best practices
542
+
543
+ As mentioned above, it's good practice to define a basic factory for each class
544
+ with only the attributes required to create it. Then, create more specific
545
+ factories that inherit from this basic parent. Factory definitions are still
546
+ code, so keep them DRY.
547
+
548
+ Associations
549
+ ------------
550
+
551
+ ### Implicit definition
552
+
553
+ It's possible to set up associations within factories. If the factory name is
554
+ the same as the association name, the factory name can be left out.
555
+
556
+ ```ruby
557
+ factory :post do
558
+ # ...
559
+ author
560
+ end
561
+ ```
562
+
563
+ ### Explicit definition
564
+
565
+ You can define associations explicitly. This can be handy especially when
566
+ [Overriding attributes](#overriding-attributes)
567
+
568
+ ```ruby
569
+ factory :post do
570
+ # ...
571
+ association :author
572
+ end
573
+ ```
574
+
575
+ ### Inline definition
576
+
577
+ You can also define associations inline within regular attributes,
578
+ but note that the value will be `nil`
579
+ when using the `attributes_for` strategy.
580
+
581
+ ```ruby
582
+ factory :post do
583
+ # ...
584
+ author { association :author }
585
+ end
586
+ ```
587
+
588
+ ### Specifying the factory
589
+
590
+ You can specify a different factory (although [Aliases](#aliases) might also
591
+ help you out here).
592
+
593
+ Implicitly:
594
+
595
+ ```ruby
596
+ factory :post do
597
+ # ...
598
+ author factory: :user
599
+ end
600
+ ```
601
+
602
+ Explicitly:
603
+
604
+ ```ruby
605
+ factory :post do
606
+ # ...
607
+ association :author, factory: :user
608
+ end
609
+ ```
610
+
611
+ Inline:
612
+
613
+ ```ruby
614
+ factory :post do
615
+ # ...
616
+ author { association :user }
617
+ end
618
+ ```
619
+
620
+ ### Overriding attributes
621
+
622
+ You can also override attributes.
623
+
624
+ Implicitly:
625
+
626
+ ```ruby
627
+ factory :post do
628
+ # ...
629
+ author factory: :author, last_name: "Writely"
630
+ end
631
+ ```
632
+
633
+ Explicitly:
634
+
635
+
636
+ ```ruby
637
+ factory :post do
638
+ # ...
639
+ association :author, last_name: "Writely"
640
+ end
641
+ ```
642
+
643
+ Or inline using attributes from the factory:
644
+
645
+ ```ruby
646
+ factory :post do
647
+ # ...
648
+ author_last_name { "Writely" }
649
+ author { association :author, last_name: author_last_name }
650
+ end
651
+ ```
652
+
653
+ ### Association overrides
654
+
655
+ Attribute overrides can be used to link associated objects:
656
+
657
+ ```ruby
658
+ FactoryBot.define do
659
+ factory :author do
660
+ name { 'Taylor' }
661
+ end
662
+
663
+ factory :post do
664
+ author
665
+ end
666
+ end
667
+
668
+ eunji = build(:author, name: 'Eunji')
669
+ post = build(:post, author: eunji)
670
+ ```
671
+
672
+ ### Build strategies
673
+
674
+ In factory\_bot 5, associations default to using the same build strategy as
675
+ their parent object:
676
+
677
+ ```ruby
678
+ FactoryBot.define do
679
+ factory :author
680
+
681
+ factory :post do
682
+ author
683
+ end
684
+ end
685
+
686
+ post = build(:post)
687
+ post.new_record? # => true
688
+ post.author.new_record? # => true
689
+
690
+ post = create(:post)
691
+ post.new_record? # => false
692
+ post.author.new_record? # => false
693
+ ```
694
+
695
+ This is different than the default behavior for previous versions of
696
+ factory\_bot, where the association strategy would not always match the strategy
697
+ of the parent object. If you want to continue using the old behavior, you can
698
+ set the `use_parent_strategy` configuration option to `false`.
699
+
700
+ ```ruby
701
+ FactoryBot.use_parent_strategy = false
702
+
703
+ # Builds and saves a User and a Post
704
+ post = create(:post)
705
+ post.new_record? # => false
706
+ post.author.new_record? # => false
707
+
708
+ # Builds and saves a User, and then builds but does not save a Post
709
+ post = build(:post)
710
+ post.new_record? # => true
711
+ post.author.new_record? # => false
712
+ ```
713
+
714
+ To not save the associated object, specify `strategy: :build` in the factory:
715
+
716
+ ```ruby
717
+ FactoryBot.use_parent_strategy = false
718
+
719
+ factory :post do
720
+ # ...
721
+ association :author, factory: :user, strategy: :build
722
+ end
723
+
724
+ # Builds a User, and then builds a Post, but does not save either
725
+ post = build(:post)
726
+ post.new_record? # => true
727
+ post.author.new_record? # => true
728
+ ```
729
+
730
+ Please note that the `strategy: :build` option must be passed to an explicit call to `association`,
731
+ and cannot be used with implicit associations:
732
+
733
+ ```ruby
734
+ factory :post do
735
+ # ...
736
+ author strategy: :build # <<< this does *not* work; causes author_id to be nil
737
+ ```
738
+
739
+ ### has_many associations
740
+
741
+ There are a few ways to generate data for a `has_many` relationship. The
742
+ simplest approach is to write a helper method in plain Ruby to tie together the
743
+ different records:
744
+
745
+ ```ruby
746
+ FactoryBot.define do
747
+ factory :post do
748
+ title { "Through the Looking Glass" }
749
+ user
750
+ end
751
+
752
+ factory :user do
753
+ name { "Rachel Sanchez" }
754
+ end
755
+ end
756
+
757
+ def user_with_posts(posts_count: 5)
758
+ FactoryBot.create(:user) do |user|
759
+ FactoryBot.create_list(:post, posts_count, user: user)
760
+ end
761
+ end
762
+
763
+ create(:user).posts.length # 0
764
+ user_with_posts.posts.length # 5
765
+ user_with_posts(posts_count: 15).posts.length # 15
766
+ ```
767
+
768
+ If you prefer to keep the object creation fully within factory\_bot, you can
769
+ build the posts in an `after(:create)` callback.
770
+
771
+
772
+ ```ruby
773
+ FactoryBot.define do
774
+ factory :post do
775
+ title { "Through the Looking Glass" }
776
+ user
777
+ end
778
+
779
+ factory :user do
780
+ name { "John Doe" }
781
+
782
+ # user_with_posts will create post data after the user has been created
783
+ factory :user_with_posts do
784
+ # posts_count is declared as a transient attribute available in the
785
+ # callback via the evaluator
786
+ transient do
787
+ posts_count { 5 }
788
+ end
789
+
790
+ # the after(:create) yields two values; the user instance itself and the
791
+ # evaluator, which stores all values from the factory, including transient
792
+ # attributes; `create_list`'s second argument is the number of records
793
+ # to create and we make sure the user is associated properly to the post
794
+ after(:create) do |user, evaluator|
795
+ create_list(:post, evaluator.posts_count, user: user)
796
+
797
+ # You may need to reload the record here, depending on your application
798
+ user.reload
799
+ end
800
+ end
801
+ end
802
+ end
803
+
804
+ create(:user).posts.length # 0
805
+ create(:user_with_posts).posts.length # 5
806
+ create(:user_with_posts, posts_count: 15).posts.length # 15
807
+ ```
808
+
809
+ Or, for a solution that works with `build`, `build_stubbed`, and `create`
810
+ (although it doesn't work well with `attributes_for`), you can use inline
811
+ associations:
812
+
813
+ ```ruby
814
+ FactoryBot.define do
815
+ factory :post do
816
+ title { "Through the Looking Glass" }
817
+ user
818
+ end
819
+
820
+ factory :user do
821
+ name { "Taylor Kim" }
822
+
823
+ factory :user_with_posts do
824
+ posts { [association(:post)] }
825
+ end
826
+ end
827
+ end
828
+
829
+ create(:user).posts.length # 0
830
+ create(:user_with_posts).posts.length # 1
831
+ build(:user_with_posts).posts.length # 1
832
+ build_stubbed(:user_with_posts).posts.length # 1
833
+ ```
834
+
835
+ For more flexibility you can combine this with the `posts_count` transient
836
+ attribute from the callback example:
837
+
838
+ ```ruby
839
+ FactoryBot.define do
840
+ factory :post do
841
+ title { "Through the Looking Glass" }
842
+ user
843
+ end
844
+
845
+ factory :user do
846
+ name { "Adiza Kumato" }
847
+
848
+ factory :user_with_posts do
849
+ transient do
850
+ posts_count { 5 }
851
+ end
852
+
853
+ posts do
854
+ Array.new(posts_count) { association(:post) }
855
+ end
856
+ end
857
+ end
858
+ end
859
+
860
+ create(:user_with_posts).posts.length # 5
861
+ create(:user_with_posts, posts_count: 15).posts.length # 15
862
+ build(:user_with_posts, posts_count: 15).posts.length # 15
863
+ build_stubbed(:user_with_posts, posts_count: 15).posts.length # 15
864
+ ```
865
+
866
+ ### has_and_belongs_to_many associations
867
+
868
+ Generating data for a `has_and_belongs_to_many` relationship is very similar
869
+ to the above `has_many` relationship, with a small change: you need to pass an
870
+ array of objects to the model's pluralized attribute name rather than a single
871
+ object to the singular version of the attribute name.
872
+
873
+
874
+ ```ruby
875
+ def profile_with_languages(languages_count: 2)
876
+ FactoryBot.create(:profile) do |profile|
877
+ FactoryBot.create_list(:language, languages_count, profiles: [profile])
878
+ end
879
+ end
880
+ ```
881
+
882
+ Or with the callback approach:
883
+
884
+ ```ruby
885
+ factory :profile_with_languages do
886
+ transient do
887
+ languages_count { 2 }
888
+ end
889
+
890
+ after(:create) do |profile, evaluator|
891
+ create_list(:language, evaluator.languages_count, profiles: [profile])
892
+ profile.reload
893
+ end
894
+ end
895
+ ```
896
+
897
+ Or the inline association approach (note the use of the `instance` method here
898
+ to refer to the profile being built):
899
+
900
+ ```ruby
901
+ factory :profile_with_languages do
902
+ transient do
903
+ languages_count { 2 }
904
+ end
905
+
906
+ languages do
907
+ Array.new(languages_count) do
908
+ association(:language, profiles: [instance])
909
+ end
910
+ end
911
+ end
912
+ ```
913
+
914
+ ### Polymorphic associations
915
+
916
+ Polymorphic associations can be handled with traits:
917
+
918
+ ```ruby
919
+ FactoryBot.define do
920
+ factory :video
921
+ factory :photo
922
+
923
+ factory :comment do
924
+ for_photo # default to the :for_photo trait if none is specified
925
+
926
+ trait :for_video do
927
+ association :commentable, factory: :video
928
+ end
929
+
930
+ trait :for_photo do
931
+ association :commentable, factory: :photo
932
+ end
933
+ end
934
+ end
935
+ ```
936
+
937
+ This allows us to do:
938
+
939
+ ```ruby
940
+ create(:comment)
941
+ create(:comment, :for_video)
942
+ create(:comment, :for_photo)
943
+ ```
944
+
945
+ ### Interconnected associations
946
+
947
+ There are limitless ways objects might be interconnected, and
948
+ factory\_bot may not always be suited to handle those relationships. In some
949
+ cases it makes sense to use factory\_bot to build each individual object, and
950
+ then to write helper methods in plain Ruby to tie those objects together.
951
+
952
+ That said, some more complex, interconnected relationships can be built in factory\_bot
953
+ using inline associations with reference to the `instance` being built.
954
+
955
+ Let's say your models look like this, where an associated `Student` and
956
+ `Profile` should both belong to the same `School`:
957
+
958
+ ```ruby
959
+ class Student < ApplicationRecord
960
+ belongs_to :school
961
+ has_one :profile
962
+ end
963
+
964
+ class Profile < ApplicationRecord
965
+ belongs_to :school
966
+ belongs_to :student
967
+ end
968
+
969
+ class School < ApplicationRecord
970
+ has_many :students
971
+ has_many :profiles
972
+ end
973
+ ```
974
+
975
+ We can ensure the student and profile are connected to each other and to the
976
+ same school with a factory like this:
977
+
978
+ ```ruby
979
+ FactoryBot.define do
980
+ factory :student do
981
+ school
982
+ profile { association :profile, student: instance, school: school }
983
+ end
984
+
985
+ factory :profile do
986
+ school
987
+ student { association :student, profile: instance, school: school }
988
+ end
989
+
990
+ factory :school
991
+ end
992
+ ```
993
+
994
+ Note that this approach works with `build`, `build_stubbed`, and `create`, but
995
+ the associations will return `nil` when using `attributes_for`.
996
+
997
+ Also, note that if you assign any attributes inside a custom `initialize_with`
998
+ (e.g. `initialize_with { new(**attributes) }`), those attributes should not refer to `instance`,
999
+ since it will be `nil`.
1000
+
1001
+ Sequences
1002
+ ---------
1003
+
1004
+ ### Global sequences
1005
+
1006
+ Unique values in a specific format (for example, e-mail addresses) can be
1007
+ generated using sequences. Sequences are defined by calling `sequence` in a
1008
+ definition block, and values in a sequence are generated by calling
1009
+ `generate`:
1010
+
1011
+ ```ruby
1012
+ # Defines a new sequence
1013
+ FactoryBot.define do
1014
+ sequence :email do |n|
1015
+ "person#{n}@example.com"
1016
+ end
1017
+ end
1018
+
1019
+ generate :email
1020
+ # => "person1@example.com"
1021
+
1022
+ generate :email
1023
+ # => "person2@example.com"
1024
+ ```
1025
+
1026
+ ### With dynamic attributes
1027
+
1028
+ Sequences can be used in dynamic attributes:
1029
+
1030
+ ```ruby
1031
+ factory :invite do
1032
+ invitee { generate(:email) }
1033
+ end
1034
+ ```
1035
+
1036
+ ### As implicit attributes
1037
+
1038
+ Or as implicit attributes:
1039
+
1040
+ ```ruby
1041
+ factory :user do
1042
+ email # Same as `email { generate(:email) }`
1043
+ end
1044
+ ```
1045
+
1046
+ Note that defining sequences as implicit attributes will not work if you have a
1047
+ factory with the same name as the sequence.
1048
+
1049
+ ### Inline sequences
1050
+
1051
+ And it's also possible to define an in-line sequence that is only used in
1052
+ a particular factory:
1053
+
1054
+ ```ruby
1055
+ factory :user do
1056
+ sequence(:email) { |n| "person#{n}@example.com" }
1057
+ end
1058
+ ```
1059
+
1060
+ With Ruby 2.7's support for [numbered parameters][], inline definitions can be
1061
+ even more abbreviated:
1062
+
1063
+ ```ruby
1064
+ factory :user do
1065
+ sequence(:email) { "person#{_1}@example.com" }
1066
+ end
1067
+ ```
1068
+
1069
+ [numbered parameters]: https://ruby-doc.org/core-2.7.1/Proc.html#class-Proc-label-Numbered+parameters
1070
+
1071
+ ### Initial value
1072
+
1073
+ You can override the initial value. Any value that responds to the `#next`
1074
+ method will work (e.g. 1, 2, 3, 'a', 'b', 'c')
1075
+
1076
+ ```ruby
1077
+ factory :user do
1078
+ sequence(:email, 1000) { |n| "person#{n}@example.com" }
1079
+ end
1080
+ ```
1081
+
1082
+ ### Without a block
1083
+
1084
+ Without a block, the value will increment itself, starting at its initial value:
1085
+
1086
+ ```ruby
1087
+ factory :post do
1088
+ sequence(:position)
1089
+ end
1090
+ ```
1091
+
1092
+ Please note, that the value for the sequence could be any Enumerable instance,
1093
+ as long as it responds to `#next`:
1094
+
1095
+ ```ruby
1096
+ factory :task do
1097
+ sequence :priority, %i[low medium high urgent].cycle
1098
+ end
1099
+ ```
1100
+
1101
+ ### Aliases
1102
+
1103
+ Sequences can also have aliases. The sequence aliases share the same counter:
1104
+
1105
+ ```ruby
1106
+ factory :user do
1107
+ sequence(:email, 1000, aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
1108
+ end
1109
+
1110
+ # will increase value counter for :email which is shared by :sender and :receiver
1111
+ generate(:sender)
1112
+ ```
1113
+
1114
+ Define aliases and use default value (1) for the counter
1115
+
1116
+ ```ruby
1117
+ factory :user do
1118
+ sequence(:email, aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
1119
+ end
1120
+ ```
1121
+
1122
+ Setting the value:
1123
+
1124
+ ```ruby
1125
+ factory :user do
1126
+ sequence(:email, 'a', aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
1127
+ end
1128
+ ```
1129
+
1130
+ The value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.
1131
+
1132
+ ### Rewinding
1133
+
1134
+ Sequences can also be rewound with `FactoryBot.rewind_sequences`:
1135
+
1136
+ ```ruby
1137
+ sequence(:email) {|n| "person#{n}@example.com" }
1138
+
1139
+ generate(:email) # "person1@example.com"
1140
+ generate(:email) # "person2@example.com"
1141
+ generate(:email) # "person3@example.com"
1142
+
1143
+ FactoryBot.rewind_sequences
1144
+
1145
+ generate(:email) # "person1@example.com"
1146
+ ```
1147
+
1148
+ This rewinds all registered sequences.
1149
+
1150
+ ### Uniqueness
1151
+
1152
+ When working with uniqueness constraints, be careful not to pass in override values that will conflict with the generated sequence values.
1153
+
1154
+ In this example the email will be the same for both users. If email must be unique, this code will error:
1155
+
1156
+ ```ruby
1157
+ factory :user do
1158
+ sequence(:email) { |n| "person#{n}@example.com" }
1159
+ end
1160
+
1161
+ FactoryBot.create(:user, email: "person1@example.com")
1162
+ FactoryBot.create(:user)
1163
+ ```
1164
+
1165
+
1166
+ Traits
1167
+ ------
1168
+
1169
+ ### Defining traits
1170
+
1171
+ Traits allow you to group attributes together and then apply them
1172
+ to any factory.
1173
+
1174
+ ```ruby
1175
+ factory :user, aliases: [:author]
1176
+
1177
+ factory :story do
1178
+ title { "My awesome story" }
1179
+ author
1180
+
1181
+ trait :published do
1182
+ published { true }
1183
+ end
1184
+
1185
+ trait :unpublished do
1186
+ published { false }
1187
+ end
1188
+
1189
+ trait :week_long_publishing do
1190
+ start_at { 1.week.ago }
1191
+ end_at { Time.now }
1192
+ end
1193
+
1194
+ trait :month_long_publishing do
1195
+ start_at { 1.month.ago }
1196
+ end_at { Time.now }
1197
+ end
1198
+
1199
+ factory :week_long_published_story, traits: [:published, :week_long_publishing]
1200
+ factory :month_long_published_story, traits: [:published, :month_long_publishing]
1201
+ factory :week_long_unpublished_story, traits: [:unpublished, :week_long_publishing]
1202
+ factory :month_long_unpublished_story, traits: [:unpublished, :month_long_publishing]
1203
+ end
1204
+ ```
1205
+
1206
+ ### As implicit attributes
1207
+
1208
+ Traits can be used as implicit attributes:
1209
+
1210
+ ```ruby
1211
+ factory :week_long_published_story_with_title, parent: :story do
1212
+ published
1213
+ week_long_publishing
1214
+ title { "Publishing that was started at #{start_at}" }
1215
+ end
1216
+ ```
1217
+
1218
+ Note that defining traits as implicit attributes will not work if you have a
1219
+ factory or sequence with the same name as the trait.
1220
+
1221
+ ### Attribute precedence
1222
+
1223
+ Traits that define the same attributes won't raise AttributeDefinitionErrors;
1224
+ the trait that defines the attribute latest gets precedence.
1225
+
1226
+ ```ruby
1227
+ factory :user do
1228
+ name { "Friendly User" }
1229
+ login { name }
1230
+
1231
+ trait :active do
1232
+ name { "John Doe" }
1233
+ status { :active }
1234
+ login { "#{name} (active)" }
1235
+ end
1236
+
1237
+ trait :inactive do
1238
+ name { "Jane Doe" }
1239
+ status { :inactive }
1240
+ login { "#{name} (inactive)" }
1241
+ end
1242
+
1243
+ trait :admin do
1244
+ admin { true }
1245
+ login { "admin-#{name}" }
1246
+ end
1247
+
1248
+ factory :active_admin, traits: [:active, :admin] # login will be "admin-John Doe"
1249
+ factory :inactive_admin, traits: [:admin, :inactive] # login will be "Jane Doe (inactive)"
1250
+ end
1251
+ ```
1252
+
1253
+ ### In child factories
1254
+
1255
+ You can override individual attributes granted by a trait in a child factory:
1256
+
1257
+ ```ruby
1258
+ factory :user do
1259
+ name { "Friendly User" }
1260
+ login { name }
1261
+
1262
+ trait :active do
1263
+ name { "John Doe" }
1264
+ status { :active }
1265
+ login { "#{name} (M)" }
1266
+ end
1267
+
1268
+ factory :brandon do
1269
+ active
1270
+ name { "Brandon" }
1271
+ end
1272
+ end
1273
+ ```
1274
+
1275
+ ### As mixins
1276
+
1277
+ Traits can be defined outside of factories and used as mixins to compose shared attributes
1278
+
1279
+ ```ruby
1280
+ FactoryBot.define do
1281
+ trait :timestamps do
1282
+ created_at { 8.days.ago }
1283
+ updated_at { 4.days.ago }
1284
+ end
1285
+
1286
+ factory :user, traits: [:timestamps] do
1287
+ username { "john_doe" }
1288
+ end
1289
+
1290
+ factory :post do
1291
+ timestamps
1292
+ title { "Traits rock" }
1293
+ end
1294
+ end
1295
+ ```
1296
+
1297
+ ### Using traits
1298
+
1299
+ Traits can also be passed in as a list of symbols when you construct an instance
1300
+ from factory\_bot.
1301
+
1302
+ ```ruby
1303
+ factory :user do
1304
+ name { "Friendly User" }
1305
+
1306
+ trait :active do
1307
+ name { "John Doe" }
1308
+ status { :active }
1309
+ end
1310
+
1311
+ trait :admin do
1312
+ admin { true }
1313
+ end
1314
+ end
1315
+
1316
+ # creates an admin user with :active status and name "Jon Snow"
1317
+ create(:user, :admin, :active, name: "Jon Snow")
1318
+ ```
1319
+
1320
+ This ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.
1321
+
1322
+ `create_list` and `build_list` methods are supported as well. Just remember to pass
1323
+ the number of instances to create/build as second parameter, as documented in the
1324
+ "Building or Creating Multiple Records" section of this file.
1325
+
1326
+ ```ruby
1327
+ factory :user do
1328
+ name { "Friendly User" }
1329
+
1330
+ trait :admin do
1331
+ admin { true }
1332
+ end
1333
+ end
1334
+
1335
+ # creates 3 admin users with :active status and name "Jon Snow"
1336
+ create_list(:user, 3, :admin, :active, name: "Jon Snow")
1337
+ ```
1338
+
1339
+ ### With associations
1340
+
1341
+ Traits can be used with associations easily too:
1342
+
1343
+ ```ruby
1344
+ factory :user do
1345
+ name { "Friendly User" }
1346
+
1347
+ trait :admin do
1348
+ admin { true }
1349
+ end
1350
+ end
1351
+
1352
+ factory :post do
1353
+ association :user, :admin, name: 'John Doe'
1354
+ end
1355
+
1356
+ # creates an admin user with name "John Doe"
1357
+ create(:post).user
1358
+ ```
1359
+
1360
+ When you're using association names that're different than the factory:
1361
+
1362
+ ```ruby
1363
+ factory :user do
1364
+ name { "Friendly User" }
1365
+
1366
+ trait :admin do
1367
+ admin { true }
1368
+ end
1369
+ end
1370
+
1371
+ factory :post do
1372
+ association :author, :admin, factory: :user, name: 'John Doe'
1373
+ # or
1374
+ association :author, factory: [:user, :admin], name: 'John Doe'
1375
+ end
1376
+
1377
+ # creates an admin user with name "John Doe"
1378
+ create(:post).author
1379
+ ```
1380
+
1381
+ ### Traits within traits
1382
+
1383
+ Traits can be used within other traits to mix in their attributes.
1384
+
1385
+ ```ruby
1386
+ factory :order do
1387
+ trait :completed do
1388
+ completed_at { 3.days.ago }
1389
+ end
1390
+
1391
+ trait :refunded do
1392
+ completed
1393
+ refunded_at { 1.day.ago }
1394
+ end
1395
+ end
1396
+ ```
1397
+
1398
+ ### With transient attributes
1399
+
1400
+ Finally, traits can accept transient attributes.
1401
+
1402
+ ```ruby
1403
+ factory :invoice do
1404
+ trait :with_amount do
1405
+ transient do
1406
+ amount { 1 }
1407
+ end
1408
+
1409
+ after(:create) do |invoice, evaluator|
1410
+ create :line_item, invoice: invoice, amount: evaluator.amount
1411
+ end
1412
+ end
1413
+ end
1414
+
1415
+ create :invoice, :with_amount, amount: 2
1416
+ ```
1417
+
1418
+ ### Enum traits
1419
+
1420
+ Given an Active Record model with an enum attribute:
1421
+
1422
+ ```ruby
1423
+ class Task < ActiveRecord::Base
1424
+ enum status: {queued: 0, started: 1, finished: 2}
1425
+ end
1426
+
1427
+ ```
1428
+
1429
+ factory\_bot will automatically define traits for each possible value of the
1430
+ enum:
1431
+
1432
+ ```ruby
1433
+ FactoryBot.define do
1434
+ factory :task
1435
+ end
1436
+
1437
+ FactoryBot.build(:task, :queued)
1438
+ FactoryBot.build(:task, :started)
1439
+ FactoryBot.build(:task, :finished)
1440
+ ```
1441
+
1442
+ Writing the traits out manually would be cumbersome, and is not necessary:
1443
+
1444
+ ```ruby
1445
+ FactoryBot.define do
1446
+ factory :task do
1447
+ trait :queued do
1448
+ status { :queued }
1449
+ end
1450
+
1451
+ trait :started do
1452
+ status { :started }
1453
+ end
1454
+
1455
+ trait :finished do
1456
+ status { :finished }
1457
+ end
1458
+ end
1459
+ end
1460
+ ```
1461
+
1462
+ If automatically defining traits for enum attributes on every factory is not
1463
+ desired, it is possible to disable the feature by setting
1464
+ `FactoryBot.automatically_define_enum_traits = false`
1465
+
1466
+ In that case, it is still possible to explicitly define traits for an enum
1467
+ attribute in a particular factory:
1468
+
1469
+ ```ruby
1470
+ FactoryBot.automatically_define_enum_traits = false
1471
+
1472
+ FactoryBot.define do
1473
+ factory :task do
1474
+ traits_for_enum(:status)
1475
+ end
1476
+ end
1477
+ ```
1478
+
1479
+ It is also possible to use this feature for other enumerable values, not
1480
+ specifically tied to Active Record enum attributes.
1481
+
1482
+ With an array:
1483
+
1484
+ ```ruby
1485
+ class Task
1486
+ attr_accessor :status
1487
+ end
1488
+
1489
+ FactoryBot.define do
1490
+ factory :task do
1491
+ traits_for_enum(:status, ["queued", "started", "finished"])
1492
+ end
1493
+ end
1494
+ ```
1495
+
1496
+ Or with a hash:
1497
+
1498
+ ```ruby
1499
+ class Task
1500
+ attr_accessor :status
1501
+ end
1502
+
1503
+ FactoryBot.define do
1504
+ factory :task do
1505
+ traits_for_enum(:status, { queued: 0, started: 1, finished: 2 })
1506
+ end
1507
+ end
1508
+ ```
1509
+
1510
+ Callbacks
1511
+ ---------
1512
+
1513
+ ### Default callbacks
1514
+
1515
+ factory\_bot makes available four callbacks for injecting some code:
1516
+
1517
+ * after(:build) - called after a factory is built (via `FactoryBot.build`, `FactoryBot.create`)
1518
+ * before(:create) - called before a factory is saved (via `FactoryBot.create`)
1519
+ * after(:create) - called after a factory is saved (via `FactoryBot.create`)
1520
+ * after(:stub) - called after a factory is stubbed (via `FactoryBot.build_stubbed`)
1521
+
1522
+ Examples:
1523
+
1524
+ ```ruby
1525
+ # Define a factory that calls the generate_hashed_password method after it is built
1526
+ factory :user do
1527
+ after(:build) { |user| generate_hashed_password(user) }
1528
+ end
1529
+ ```
1530
+
1531
+ Note that you'll have an instance of the user in the block. This can be useful.
1532
+
1533
+ ### Multiple callbacks
1534
+
1535
+ You can also define multiple types of callbacks on the same factory:
1536
+
1537
+ ```ruby
1538
+ factory :user do
1539
+ after(:build) { |user| do_something_to(user) }
1540
+ after(:create) { |user| do_something_else_to(user) }
1541
+ end
1542
+ ```
1543
+
1544
+ Factories can also define any number of the same kind of callback. These
1545
+ callbacks will be executed in the order they are specified:
1546
+
1547
+ ```ruby
1548
+ factory :user do
1549
+ after(:create) { this_runs_first }
1550
+ after(:create) { then_this }
1551
+ end
1552
+ ```
1553
+
1554
+ Calling `create` will invoke both `after_build` and `after_create` callbacks.
1555
+
1556
+ Also, like standard attributes, child factories will inherit (and can also
1557
+ define) callbacks from their parent factory.
1558
+
1559
+ Multiple callbacks can be assigned to run a block; this is useful when building
1560
+ various strategies that run the same code (since there are no callbacks that are
1561
+ shared across all strategies).
1562
+
1563
+ ```ruby
1564
+ factory :user do
1565
+ callback(:after_stub, :before_create) { do_something }
1566
+ after(:stub, :create) { do_something_else }
1567
+ before(:create, :custom) { do_a_third_thing }
1568
+ end
1569
+ ```
1570
+
1571
+ ### Global callbacks
1572
+
1573
+ To override callbacks for all factories, define them within the
1574
+ `FactoryBot.define` block:
1575
+
1576
+ ```ruby
1577
+ FactoryBot.define do
1578
+ after(:build) { |object| puts "Built #{object}" }
1579
+ after(:create) { |object| AuditLog.create(attrs: object.attributes) }
1580
+
1581
+ factory :user do
1582
+ name { "John Doe" }
1583
+ end
1584
+ end
1585
+ ```
1586
+
1587
+ ### Symbol#to_proc
1588
+
1589
+ You can call callbacks that rely on `Symbol#to_proc`:
1590
+
1591
+ ```ruby
1592
+ # app/models/user.rb
1593
+ class User < ActiveRecord::Base
1594
+ def confirm!
1595
+ # confirm the user account
1596
+ end
1597
+ end
1598
+
1599
+ # spec/factories.rb
1600
+ FactoryBot.define do
1601
+ factory :user do
1602
+ after :create, &:confirm!
1603
+ end
1604
+ end
1605
+
1606
+ create(:user) # creates the user and confirms it
1607
+ ```
1608
+
1609
+ Modifying factories
1610
+ -------------------
1611
+
1612
+ If you're given a set of factories (say, from a gem developer) but want to
1613
+ change them to fit into your application better, you can modify that factory
1614
+ instead of creating a child factory and adding attributes there.
1615
+
1616
+ If a gem were to give you a User factory:
1617
+
1618
+ ```ruby
1619
+ FactoryBot.define do
1620
+ factory :user do
1621
+ full_name { "John Doe" }
1622
+ sequence(:username) { |n| "user#{n}" }
1623
+ password { "password" }
1624
+ end
1625
+ end
1626
+ ```
1627
+
1628
+ Instead of creating a child factory that added additional attributes:
1629
+
1630
+ ```ruby
1631
+ FactoryBot.define do
1632
+ factory :application_user, parent: :user do
1633
+ full_name { "Jane Doe" }
1634
+ date_of_birth { 21.years.ago }
1635
+ health { 90 }
1636
+ end
1637
+ end
1638
+ ```
1639
+
1640
+ You could modify that factory instead.
1641
+
1642
+ ```ruby
1643
+ FactoryBot.modify do
1644
+ factory :user do
1645
+ full_name { "Jane Doe" }
1646
+ date_of_birth { 21.years.ago }
1647
+ health { 90 }
1648
+ end
1649
+ end
1650
+ ```
1651
+
1652
+ When modifying a factory, you can change any of the attributes you want (aside from callbacks).
1653
+
1654
+ `FactoryBot.modify` must be called outside of a `FactoryBot.define` block as it operates on factories differently.
1655
+
1656
+ A caveat: you can only modify factories (not sequences or traits) and callbacks *still compound as they normally would*. So, if
1657
+ the factory you're modifying defines an `after(:create)` callback, you defining an `after(:create)` won't override it, it'll just get run after the first callback.
1658
+
1659
+ Building or Creating Multiple Records
1660
+ -------------------------------------
1661
+
1662
+ Sometimes, you'll want to create or build multiple instances of a factory at once.
1663
+
1664
+ ```ruby
1665
+ built_users = build_list(:user, 25)
1666
+ created_users = create_list(:user, 25)
1667
+ ```
1668
+
1669
+ These methods will build or create a specific amount of factories and return them as an array.
1670
+ To set the attributes for each of the factories, you can pass in a hash as you normally would.
1671
+
1672
+ ```ruby
1673
+ twenty_year_olds = build_list(:user, 25, date_of_birth: 20.years.ago)
1674
+ ```
1675
+
1676
+ In order to set different attributes for each factory, these methods may be passed a block, with the factory and the index as parameters:
1677
+
1678
+ ```ruby
1679
+ twenty_somethings = build_list(:user, 10) do |user, i|
1680
+ user.date_of_birth = (20 + i).years.ago
1681
+ end
1682
+ ```
1683
+
1684
+ `create_list` passes saved instances into the block. If you modify the instance, you must save it again:
1685
+
1686
+ ```ruby
1687
+ twenty_somethings = create_list(:user, 10) do |user, i|
1688
+ user.date_of_birth = (20 + i).years.ago
1689
+ user.save!
1690
+ end
1691
+ ```
1692
+
1693
+ `build_stubbed_list` will give you fully stubbed out instances:
1694
+
1695
+ ```ruby
1696
+ stubbed_users = build_stubbed_list(:user, 25) # array of stubbed users
1697
+ ```
1698
+
1699
+ There's also a set of `*_pair` methods for creating two records at a time:
1700
+
1701
+ ```ruby
1702
+ built_users = build_pair(:user) # array of two built users
1703
+ created_users = create_pair(:user) # array of two created users
1704
+ ```
1705
+
1706
+ If you need multiple attribute hashes, `attributes_for_list` will generate them:
1707
+
1708
+ ```ruby
1709
+ users_attrs = attributes_for_list(:user, 25) # array of attribute hashes
1710
+ ```
1711
+
1712
+ Linting Factories
1713
+ -----------------
1714
+
1715
+ factory\_bot allows for linting known factories:
1716
+
1717
+ ```ruby
1718
+ FactoryBot.lint
1719
+ ```
1720
+
1721
+ `FactoryBot.lint` creates each factory and catches any exceptions raised
1722
+ during the creation process. `FactoryBot::InvalidFactoryError` is raised with
1723
+ a list of factories (and corresponding exceptions) for factories which could
1724
+ not be created.
1725
+
1726
+ Recommended usage of `FactoryBot.lint`
1727
+ is to run this in a task
1728
+ before your test suite is executed.
1729
+ Running it in a `before(:suite)`,
1730
+ will negatively impact the performance
1731
+ of your tests
1732
+ when running single tests.
1733
+
1734
+ Example Rake task:
1735
+
1736
+ ```ruby
1737
+ # lib/tasks/factory_bot.rake
1738
+ namespace :factory_bot do
1739
+ desc "Verify that all FactoryBot factories are valid"
1740
+ task lint: :environment do
1741
+ if Rails.env.test?
1742
+ conn = ActiveRecord::Base.connection
1743
+ conn.transaction do
1744
+ FactoryBot.lint
1745
+ raise ActiveRecord::Rollback
1746
+ end
1747
+ else
1748
+ system("bundle exec rake factory_bot:lint RAILS_ENV='test'")
1749
+ fail if $?.exitstatus.nonzero?
1750
+ end
1751
+ end
1752
+ end
1753
+ ```
1754
+
1755
+ After calling `FactoryBot.lint`, you'll likely want to clear out the
1756
+ database, as records will most likely be created. The provided example above
1757
+ uses an sql transaction and rollback to leave the database clean.
1758
+
1759
+ You can lint factories selectively by passing only factories you want linted:
1760
+
1761
+ ```ruby
1762
+ factories_to_lint = FactoryBot.factories.reject do |factory|
1763
+ factory.name =~ /^old_/
1764
+ end
1765
+
1766
+ FactoryBot.lint factories_to_lint
1767
+ ```
1768
+
1769
+ This would lint all factories that aren't prefixed with `old_`.
1770
+
1771
+ Traits can also be linted. This option verifies that each
1772
+ and every trait of a factory generates a valid object on its own.
1773
+ This is turned on by passing `traits: true` to the `lint` method:
1774
+
1775
+ ```ruby
1776
+ FactoryBot.lint traits: true
1777
+ ```
1778
+
1779
+ This can also be combined with other arguments:
1780
+
1781
+ ```ruby
1782
+ FactoryBot.lint factories_to_lint, traits: true
1783
+ ```
1784
+
1785
+ You can also specify the strategy used for linting:
1786
+
1787
+ ```ruby
1788
+ FactoryBot.lint strategy: :build
1789
+ ```
1790
+
1791
+ Verbose linting will include full backtraces for each error, which can be
1792
+ helpful for debugging:
1793
+
1794
+ ```ruby
1795
+ FactoryBot.lint verbose: true
1796
+ ```
1797
+
1798
+ Custom Construction
1799
+ -------------------
1800
+
1801
+ If you want to use factory\_bot to construct an object where some attributes
1802
+ are passed to `initialize` or if you want to do something other than simply
1803
+ calling `new` on your build class, you can override the default behavior by
1804
+ defining `initialize_with` on your factory. Example:
1805
+
1806
+ ```ruby
1807
+ # user.rb
1808
+ class User
1809
+ attr_accessor :name, :email
1810
+
1811
+ def initialize(name)
1812
+ @name = name
1813
+ end
1814
+ end
1815
+
1816
+ # factories.rb
1817
+ sequence(:email) { |n| "person#{n}@example.com" }
1818
+
1819
+ factory :user do
1820
+ name { "Jane Doe" }
1821
+ email
1822
+
1823
+ initialize_with { new(name) }
1824
+ end
1825
+
1826
+ build(:user).name # Jane Doe
1827
+ ```
1828
+
1829
+ Although factory\_bot is written to work with ActiveRecord out of the box, it
1830
+ can also work with any Ruby class. For maximum compatibility with ActiveRecord,
1831
+ the default initializer builds all instances by calling `new` on your build class
1832
+ without any arguments. It then calls attribute writer methods to assign all the
1833
+ attribute values. While that works fine for ActiveRecord, it actually doesn't
1834
+ work for almost any other Ruby class.
1835
+
1836
+ You can override the initializer in order to:
1837
+
1838
+ * Build non-ActiveRecord objects that require arguments to `initialize`
1839
+ * Use a method other than `new` to instantiate the instance
1840
+ * Do wild things like decorate the instance after it's built
1841
+
1842
+ When using `initialize_with`, you don't have to declare the class itself when
1843
+ calling `new`; however, any other class methods you want to call will have to
1844
+ be called on the class explicitly.
1845
+
1846
+ For example:
1847
+
1848
+ ```ruby
1849
+ factory :user do
1850
+ name { "John Doe" }
1851
+
1852
+ initialize_with { User.build_with_name(name) }
1853
+ end
1854
+ ```
1855
+
1856
+ You can also access all public attributes within the `initialize_with` block
1857
+ by calling `attributes`:
1858
+
1859
+ ```ruby
1860
+ factory :user do
1861
+ transient do
1862
+ comments_count { 5 }
1863
+ end
1864
+
1865
+ name "John Doe"
1866
+
1867
+ initialize_with { new(**attributes) }
1868
+ end
1869
+ ```
1870
+
1871
+ This will build a hash of all attributes to be passed to `new`. It won't
1872
+ include transient attributes, but everything else defined in the factory will be
1873
+ passed (associations, evaluated sequences, etc.)
1874
+
1875
+ You can define `initialize_with` for all factories by including it in the
1876
+ `FactoryBot.define` block:
1877
+
1878
+ ```ruby
1879
+ FactoryBot.define do
1880
+ initialize_with { new("Awesome first argument") }
1881
+ end
1882
+ ```
1883
+
1884
+ When using `initialize_with`, attributes accessed from within the `initialize_with`
1885
+ block are assigned *only* in the constructor; this equates to roughly the
1886
+ following code:
1887
+
1888
+ ```ruby
1889
+ FactoryBot.define do
1890
+ factory :user do
1891
+ initialize_with { new(name) }
1892
+
1893
+ name { 'value' }
1894
+ end
1895
+ end
1896
+
1897
+ build(:user)
1898
+ # runs
1899
+ User.new('value')
1900
+ ```
1901
+
1902
+ This prevents duplicate assignment; in versions of factory\_bot before 4.0, it
1903
+ would run this:
1904
+
1905
+ ```ruby
1906
+ FactoryBot.define do
1907
+ factory :user do
1908
+ initialize_with { new(name) }
1909
+
1910
+ name { 'value' }
1911
+ end
1912
+ end
1913
+
1914
+ build(:user)
1915
+ # runs
1916
+ user = User.new('value')
1917
+ user.name = 'value'
1918
+ ```
1919
+
1920
+ Custom Strategies
1921
+ -----------------
1922
+
1923
+ There are times where you may want to extend behavior of factory\_bot by
1924
+ adding a custom build strategy.
1925
+
1926
+ Strategies define two methods: `association` and `result`. `association`
1927
+ receives a `FactoryBot::FactoryRunner` instance, upon which you can call
1928
+ `run`, overriding the strategy if you want. The second method, `result`,
1929
+ receives a `FactoryBot::Evaluation` instance. It provides a way to trigger
1930
+ callbacks (with `notify`), `object` or `hash` (to get the result instance or a
1931
+ hash based on the attributes defined in the factory), and `create`, which
1932
+ executes the `to_create` callback defined on the factory.
1933
+
1934
+ To understand how factory\_bot uses strategies internally, it's probably
1935
+ easiest to just view the source for each of the four default strategies.
1936
+
1937
+ Here's an example of composing a strategy using
1938
+ `FactoryBot::Strategy::Create` to build a JSON representation of your model.
1939
+
1940
+ ```ruby
1941
+ class JsonStrategy
1942
+ def initialize
1943
+ @strategy = FactoryBot.strategy_by_name(:create).new
1944
+ end
1945
+
1946
+ delegate :association, to: :@strategy
1947
+
1948
+ def result(evaluation)
1949
+ @strategy.result(evaluation).to_json
1950
+ end
1951
+
1952
+ def to_sym
1953
+ :json
1954
+ end
1955
+ end
1956
+ ```
1957
+
1958
+ For factory\_bot to recognize the new strategy, you can register it:
1959
+
1960
+ ```ruby
1961
+ FactoryBot.register_strategy(:json, JsonStrategy)
1962
+ ```
1963
+
1964
+ This allows you to call
1965
+
1966
+ ```ruby
1967
+ FactoryBot.json(:user)
1968
+ ```
1969
+
1970
+ Finally, you can override factory\_bot's own strategies if you'd like by
1971
+ registering a new object in place of the strategies.
1972
+
1973
+ Custom Callbacks
1974
+ ----------------
1975
+
1976
+ Custom callbacks can be defined if you're using custom strategies:
1977
+
1978
+ ```ruby
1979
+ class JsonStrategy
1980
+ def initialize
1981
+ @strategy = FactoryBot.strategy_by_name(:create).new
1982
+ end
1983
+
1984
+ delegate :association, to: :@strategy
1985
+
1986
+ def result(evaluation)
1987
+ result = @strategy.result(evaluation)
1988
+ evaluation.notify(:before_json, result)
1989
+
1990
+ result.to_json.tap do |json|
1991
+ evaluation.notify(:after_json, json)
1992
+ evaluation.notify(:make_json_awesome, json)
1993
+ end
1994
+ end
1995
+
1996
+ def to_sym
1997
+ :json
1998
+ end
1999
+ end
2000
+
2001
+ FactoryBot.register_strategy(:json, JsonStrategy)
2002
+
2003
+ FactoryBot.define do
2004
+ factory :user do
2005
+ before(:json) { |user| do_something_to(user) }
2006
+ after(:json) { |user_json| do_something_to(user_json) }
2007
+ callback(:make_json_awesome) { |user_json| do_something_to(user_json) }
2008
+ end
2009
+ end
2010
+ ```
2011
+
2012
+ Custom Methods to Persist Objects
2013
+ ---------------------------------
2014
+
2015
+ By default, creating a record will call `save!` on the instance; since this
2016
+ may not always be ideal, you can override that behavior by defining
2017
+ `to_create` on the factory:
2018
+
2019
+ ```ruby
2020
+ factory :different_orm_model do
2021
+ to_create { |instance| instance.persist! }
2022
+ end
2023
+ ```
2024
+
2025
+ To disable the persistence method altogether on create, you can `skip_create`
2026
+ for that factory:
2027
+
2028
+ ```ruby
2029
+ factory :user_without_database do
2030
+ skip_create
2031
+ end
2032
+ ```
2033
+
2034
+ To override `to_create` for all factories, define it within the
2035
+ `FactoryBot.define` block:
2036
+
2037
+ ```ruby
2038
+ FactoryBot.define do
2039
+ to_create { |instance| instance.persist! }
2040
+
2041
+
2042
+ factory :user do
2043
+ name { "John Doe" }
2044
+ end
2045
+ end
2046
+ ```
2047
+
2048
+ ActiveSupport Instrumentation
2049
+ -----------------------------
2050
+
2051
+ In order to track what factories are created (and with what build strategy),
2052
+ `ActiveSupport::Notifications` are included to provide a way to subscribe to
2053
+ factories being compiled and run. One example would be to track factories based on a
2054
+ threshold of execution time.
2055
+
2056
+ ```ruby
2057
+ ActiveSupport::Notifications.subscribe("factory_bot.run_factory") do |name, start, finish, id, payload|
2058
+ execution_time_in_seconds = finish - start
2059
+
2060
+ if execution_time_in_seconds >= 0.5
2061
+ $stderr.puts "Slow factory: #{payload[:name]} using strategy #{payload[:strategy]}"
2062
+ end
2063
+ end
2064
+ ```
2065
+
2066
+ Another example would be tracking all factories and how they're used
2067
+ throughout your test suite. If you're using RSpec, it's as simple as adding a
2068
+ `before(:suite)` and `after(:suite)`:
2069
+
2070
+ ```ruby
2071
+ factory_bot_results = {}
2072
+ config.before(:suite) do
2073
+ ActiveSupport::Notifications.subscribe("factory_bot.run_factory") do |name, start, finish, id, payload|
2074
+ factory_name = payload[:name]
2075
+ strategy_name = payload[:strategy]
2076
+ factory_bot_results[factory_name] ||= {}
2077
+ factory_bot_results[factory_name][strategy_name] ||= 0
2078
+ factory_bot_results[factory_name][strategy_name] += 1
2079
+ end
2080
+ end
2081
+
2082
+ config.after(:suite) do
2083
+ puts factory_bot_results
2084
+ end
2085
+ ```
2086
+
2087
+ You can also subscribe to `factory_bot.before_run_factory` to be notified
2088
+ before a factory is run. This is useful for building a factory call stack when
2089
+ debugging deeply nested associations:
2090
+
2091
+ ```ruby
2092
+ factory_call_stack = []
2093
+
2094
+ ActiveSupport::Notifications.subscribe("factory_bot.before_run_factory") do |name, start, finish, id, payload|
2095
+ factory_call_stack.push(payload[:name])
2096
+ end
2097
+
2098
+ ActiveSupport::Notifications.subscribe("factory_bot.run_factory") do |name, start, finish, id, payload|
2099
+ factory_call_stack.pop
2100
+ end
2101
+ ```
2102
+
2103
+ The payload for `factory_bot.before_run_factory` contains the same keys as
2104
+ `factory_bot.run_factory`: `:name`, `:strategy`, `:traits`, `:overrides`, and
2105
+ `:factory`.
2106
+
2107
+ Another example could involve tracking the attributes and traits that factories are compiled with. If you're using RSpec, you could add `before(:suite)` and `after(:suite)` blocks that subscribe to `factory_bot.compile_factory` notifications:
2108
+
2109
+ ```ruby
2110
+ factory_bot_results = {}
2111
+ config.before(:suite) do
2112
+ ActiveSupport::Notifications.subscribe("factory_bot.compile_factory") do |name, start, finish, id, payload|
2113
+ factory_name = payload[:name]
2114
+ factory_class = payload[:class]
2115
+ attributes = payload[:attributes]
2116
+ traits = payload[:traits]
2117
+ factory_bot_results[factory_class] ||= {}
2118
+ factory_bot_results[factory_class][factory_name] = {
2119
+ attributes: attributes.map(&:name)
2120
+ traits: traits.map(&:name)
2121
+ }
2122
+ end
2123
+ end
2124
+
2125
+ config.after(:suite) do
2126
+ puts factory_bot_results
2127
+ end
2128
+ ```
2129
+
2130
+ Rails Preloaders and RSpec
2131
+ --------------------------
2132
+
2133
+ When running RSpec with a Rails preloader such as `spring` or `zeus`, it's possible
2134
+ to encounter an `ActiveRecord::AssociationTypeMismatch` error when creating a factory
2135
+ with associations, as below:
2136
+
2137
+ ```ruby
2138
+ FactoryBot.define do
2139
+ factory :united_states, class: "Location" do
2140
+ name { 'United States' }
2141
+ association :location_group, factory: :north_america
2142
+ end
2143
+
2144
+ factory :north_america, class: "LocationGroup" do
2145
+ name { 'North America' }
2146
+ end
2147
+ end
2148
+ ```
2149
+
2150
+ The error occurs during the run of the test suite:
2151
+
2152
+ ```
2153
+ Failure/Error: united_states = create(:united_states)
2154
+ ActiveRecord::AssociationTypeMismatch:
2155
+ LocationGroup(#70251250797320) expected, got LocationGroup(#70251200725840)
2156
+ ```
2157
+
2158
+ The two possible solutions are to either run the suite without the preloader, or
2159
+ to add `FactoryBot.reload` to the RSpec configuration, like so:
2160
+
2161
+ ```ruby
2162
+ RSpec.configure do |config|
2163
+ config.before(:suite) { FactoryBot.reload }
2164
+ end
2165
+ ```
2166
+
2167
+ Using Without Bundler
2168
+ ---------------------
2169
+
2170
+ If you're not using Bundler, be sure to have the gem installed and call:
2171
+
2172
+ ```ruby
2173
+ require 'factory_bot'
2174
+ ```
2175
+
2176
+ Once required, assuming you have a directory structure of `spec/factories` or
2177
+ `test/factories`, all you'll need to do is run:
2178
+
2179
+ ```ruby
2180
+ FactoryBot.find_definitions
2181
+ ```
2182
+
2183
+ If you're using a separate directory structure for your factories, you can
2184
+ change the definition file paths before trying to find definitions:
2185
+
2186
+ ```ruby
2187
+ FactoryBot.definition_file_paths = %w(custom_factories_directory)
2188
+ FactoryBot.find_definitions
2189
+ ```
2190
+
2191
+ If you don't have a separate directory of factories and would like to define
2192
+ them inline, that's possible as well:
2193
+
2194
+ ```ruby
2195
+ require 'factory_bot'
2196
+
2197
+ FactoryBot.define do
2198
+ factory :user do
2199
+ name { 'John Doe' }
2200
+ date_of_birth { 21.years.ago }
2201
+ end
2202
+ end
2203
+ ```