factory_bot 4.11.1 → 6.2.0

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +58 -13
  3. data/GETTING_STARTED.md +785 -153
  4. data/LICENSE +1 -1
  5. data/NEWS.md +379 -0
  6. data/README.md +20 -30
  7. data/lib/factory_bot/aliases.rb +2 -2
  8. data/lib/factory_bot/attribute/association.rb +2 -2
  9. data/lib/factory_bot/attribute/dynamic.rb +3 -2
  10. data/lib/factory_bot/attribute.rb +4 -39
  11. data/lib/factory_bot/attribute_assigner.rb +24 -10
  12. data/lib/factory_bot/attribute_list.rb +3 -2
  13. data/lib/factory_bot/callback.rb +4 -11
  14. data/lib/factory_bot/configuration.rb +15 -19
  15. data/lib/factory_bot/declaration/association.rb +33 -3
  16. data/lib/factory_bot/declaration/dynamic.rb +3 -1
  17. data/lib/factory_bot/declaration/implicit.rb +7 -2
  18. data/lib/factory_bot/declaration.rb +5 -5
  19. data/lib/factory_bot/declaration_list.rb +3 -3
  20. data/lib/factory_bot/decorator/attribute_hash.rb +1 -1
  21. data/lib/factory_bot/decorator/invocation_tracker.rb +2 -1
  22. data/lib/factory_bot/decorator.rb +20 -4
  23. data/lib/factory_bot/definition.rb +69 -21
  24. data/lib/factory_bot/definition_hierarchy.rb +1 -11
  25. data/lib/factory_bot/definition_proxy.rb +119 -64
  26. data/lib/factory_bot/enum.rb +27 -0
  27. data/lib/factory_bot/errors.rb +7 -4
  28. data/lib/factory_bot/evaluation.rb +1 -1
  29. data/lib/factory_bot/evaluator.rb +10 -11
  30. data/lib/factory_bot/evaluator_class_definer.rb +1 -1
  31. data/lib/factory_bot/factory.rb +12 -12
  32. data/lib/factory_bot/factory_runner.rb +4 -4
  33. data/lib/factory_bot/find_definitions.rb +2 -2
  34. data/lib/factory_bot/internal.rb +91 -0
  35. data/lib/factory_bot/linter.rb +41 -28
  36. data/lib/factory_bot/null_factory.rb +13 -4
  37. data/lib/factory_bot/null_object.rb +2 -6
  38. data/lib/factory_bot/registry.rb +17 -8
  39. data/lib/factory_bot/reload.rb +2 -3
  40. data/lib/factory_bot/sequence.rb +5 -6
  41. data/lib/factory_bot/strategy/stub.rb +37 -32
  42. data/lib/factory_bot/strategy_calculator.rb +1 -1
  43. data/lib/factory_bot/strategy_syntax_method_registrar.rb +13 -2
  44. data/lib/factory_bot/syntax/default.rb +13 -25
  45. data/lib/factory_bot/syntax/methods.rb +32 -9
  46. data/lib/factory_bot/syntax.rb +2 -2
  47. data/lib/factory_bot/trait.rb +7 -4
  48. data/lib/factory_bot/version.rb +1 -1
  49. data/lib/factory_bot.rb +71 -140
  50. metadata +46 -34
  51. data/NEWS +0 -306
  52. data/lib/factory_bot/attribute/static.rb +0 -16
  53. data/lib/factory_bot/declaration/static.rb +0 -26
  54. data/lib/factory_bot/decorator/class_key_hash.rb +0 -28
data/GETTING_STARTED.md CHANGED
@@ -1,36 +1,111 @@
1
1
  Getting Started
2
2
  ===============
3
3
 
4
- Update Your Gemfile
5
- -------------------
4
+ * [Setup](#setup)
5
+ + [Update Your Gemfile](#update-your-gemfile)
6
+ + [Configure your test suite](#configure-your-test-suite)
7
+ - [RSpec](#rspec)
8
+ - [Test::Unit](#testunit)
9
+ - [Cucumber](#cucumber)
10
+ - [Spinach](#spinach)
11
+ - [Minitest](#minitest)
12
+ - [Minitest::Spec](#minitestspec)
13
+ - [minitest-rails](#minitest-rails)
14
+ * [Defining factories](#defining-factories)
15
+ + [Factory name and attributes](#factory-name-and-attributes)
16
+ + [Specifying the class explicitly](#specifying-the-class-explicitly)
17
+ + [Hash attributes](#hash-attributes)
18
+ + [Best practices](#best-practices)
19
+ + [Definition file paths](#definition-file-paths)
20
+ + [Static Attributes](#static-attributes)
21
+ * [Using factories](#using-factories)
22
+ + [Build strategies](#build-strategies)
23
+ + [Attribute overrides](#attribute-overrides)
24
+ + [`build_stubbed` and `Marshal.dump`](#build_stubbed-and-marshaldump)
25
+ * [Aliases](#aliases)
26
+ * [Dependent Attributes](#dependent-attributes)
27
+ * [Transient Attributes](#transient-attributes)
28
+ + [With other attributes](#with-other-attributes)
29
+ + [With `attributes_for`](#with-attributes_for)
30
+ + [With callbacks](#with-callbacks)
31
+ + [With associations](#with-associations)
32
+ * [Method Name / Reserved Word Attributes](#method-name--reserved-word-attributes)
33
+ * [Inheritance](#inheritance)
34
+ + [Nested factories](#nested-factories)
35
+ + [Assigning parent explicitly](#assigning-parent-explicitly)
36
+ + [Best practices](#best-practices-1)
37
+ * [Associations](#associations)
38
+ + [Implicit definition](#implicit-definition)
39
+ + [Explicit definition](#explicit-definition)
40
+ + [Inline definition](#inline-definition)
41
+ + [Specifying the factory](#specifying-the-factory)
42
+ + [Overriding attributes](#overriding-attributes)
43
+ + [Association overrides](#association-overrides)
44
+ + [Build strategies](#build-strategies-1)
45
+ + [`has_many` associations](#has_many-associations)
46
+ + [`has_and_belongs_to_many` associations](#has_and_belongs_to_many-associations)
47
+ + [Polymorphic associations](#polymorphic-associations)
48
+ + [Interconnected associations](#interconnected-associations)
49
+ * [Sequences](#sequences)
50
+ + [Global sequences](#global-sequences)
51
+ + [With dynamic attributes](#with-dynamic-attributes)
52
+ + [As implicit attributes](#as-implicit-attributes)
53
+ + [Inline sequences](#inline-sequences)
54
+ + [Initial value](#initial-value)
55
+ + [Without a block](#without-a-block)
56
+ + [Aliases](#aliases-1)
57
+ + [Rewinding](#rewinding)
58
+ + [Uniqueness](#uniqueness)
59
+ * [Traits](#traits)
60
+ + [Defining traits](#defining-traits)
61
+ + [As implicit attributes](#as-implicit-attributes-1)
62
+ + [Attribute precedence](#attribute-precedence)
63
+ + [In child factories](#in-child-factories)
64
+ + [Using traits](#using-traits)
65
+ + [With associations](#with-associations-1)
66
+ + [Traits within traits](#traits-within-traits)
67
+ + [With transient attributes](#with-transient-attributes)
68
+ + [Enum traits](#enum-traits)
69
+ * [Callbacks](#callbacks)
70
+ + [Default callbacks](#default-callbacks)
71
+ + [Multiple callbacks](#multiple-callbacks)
72
+ + [Global callbacks](#global-callbacks)
73
+ + [Symbol#to_proc](#symbolto_proc)
74
+ * [Modifying factories](#modifying-factories)
75
+ * [Building or Creating Multiple Records](#building-or-creating-multiple-records)
76
+ * [Linting Factories](#linting-factories)
77
+ * [Custom Construction](#custom-construction)
78
+ * [Custom Strategies](#custom-strategies)
79
+ * [Custom Callbacks](#custom-callbacks)
80
+ * [Custom Methods to Persist Objects](#custom-methods-to-persist-objects)
81
+ * [ActiveSupport Instrumentation](#activesupport-instrumentation)
82
+ * [Rails Preloaders and RSpec](#rails-preloaders-and-rspec)
83
+ * [Using Without Bundler](#using-without-bundler)
84
+
85
+ Setup
86
+ -----
87
+
88
+ ### Update Your Gemfile
6
89
 
7
- If you're using Rails, you'll need to change the required version of `factory_bot_rails`:
90
+ If you're using Rails:
8
91
 
9
92
  ```ruby
10
- gem "factory_bot_rails", "~> 4.0"
93
+ gem "factory_bot_rails"
11
94
  ```
12
95
 
13
- If you're *not* using Rails, you'll just have to change the required version of `factory_bot`:
96
+ If you're *not* using Rails:
14
97
 
15
98
  ```ruby
16
- gem "factory_bot", "~> 4.0"
17
- ```
18
-
19
- JRuby users: factory_bot works with JRuby starting with 1.6.7.2 (latest stable, as per July 2012).
20
- JRuby has to be used in 1.9 mode, for that, use JRUBY_OPTS environment variable:
21
-
22
- ```bash
23
- export JRUBY_OPTS=--1.9
99
+ gem "factory_bot"
24
100
  ```
25
101
 
26
- Once your Gemfile is updated, you'll want to update your bundle.
102
+ ### Configure your test suite
27
103
 
28
- Configure your test suite
29
- -------------------------
104
+ #### RSpec
30
105
 
31
- ### RSpec
32
-
33
- If you're using Rails:
106
+ If you're using Rails, add the following configuration to
107
+ `spec/support/factory_bot.rb` and be sure to require that file in
108
+ `rails_helper.rb`:
34
109
 
35
110
  ```ruby
36
111
  RSpec.configure do |config|
@@ -50,7 +125,7 @@ RSpec.configure do |config|
50
125
  end
51
126
  ```
52
127
 
53
- ### Test::Unit
128
+ #### Test::Unit
54
129
 
55
130
  ```ruby
56
131
  class Test::Unit::TestCase
@@ -58,14 +133,14 @@ class Test::Unit::TestCase
58
133
  end
59
134
  ```
60
135
 
61
- ### Cucumber
136
+ #### Cucumber
62
137
 
63
138
  ```ruby
64
139
  # env.rb (Rails example location - RAILS_ROOT/features/support/env.rb)
65
140
  World(FactoryBot::Syntax::Methods)
66
141
  ```
67
142
 
68
- ### Spinach
143
+ #### Spinach
69
144
 
70
145
  ```ruby
71
146
  class Spinach::FeatureSteps
@@ -73,7 +148,7 @@ class Spinach::FeatureSteps
73
148
  end
74
149
  ```
75
150
 
76
- ### Minitest
151
+ #### Minitest
77
152
 
78
153
  ```ruby
79
154
  class Minitest::Unit::TestCase
@@ -81,7 +156,7 @@ class Minitest::Unit::TestCase
81
156
  end
82
157
  ```
83
158
 
84
- ### Minitest::Spec
159
+ #### Minitest::Spec
85
160
 
86
161
  ```ruby
87
162
  class Minitest::Spec
@@ -89,7 +164,7 @@ class Minitest::Spec
89
164
  end
90
165
  ```
91
166
 
92
- ### minitest-rails
167
+ #### minitest-rails
93
168
 
94
169
  ```ruby
95
170
  class ActiveSupport::TestCase
@@ -97,12 +172,16 @@ class ActiveSupport::TestCase
97
172
  end
98
173
  ```
99
174
 
100
- If you do not include `FactoryBot::Syntax::Methods` in your test suite, then all factory_bot methods will need to be prefaced with `FactoryBot`.
175
+ If you do not include `FactoryBot::Syntax::Methods` in your test suite, then all
176
+ factory\_bot methods will need to be prefaced with `FactoryBot`.
101
177
 
102
178
  Defining factories
103
179
  ------------------
104
180
 
105
- Each factory has a name and a set of attributes. The name is used to guess the class of the object by default, but it's possible to explicitly specify it:
181
+ ### Factory name and attributes
182
+
183
+ Each factory has a name and a set of attributes. The name is used to guess the
184
+ class of the object by default:
106
185
 
107
186
  ```ruby
108
187
  # This will guess the User class
@@ -112,16 +191,28 @@ FactoryBot.define do
112
191
  last_name { "Doe" }
113
192
  admin { false }
114
193
  end
115
-
116
- # This will use the User class (Admin would have been guessed)
117
- factory :admin, class: User do
118
- first_name { "Admin" }
119
- last_name { "User" }
120
- admin { true }
121
- end
122
194
  end
123
195
  ```
124
196
 
197
+ ### Specifying the class explicitly
198
+
199
+ It is also possible to explicitly specify the class:
200
+
201
+ ```ruby
202
+ # This will use the User class (otherwise Admin would have been guessed)
203
+ factory :admin, class: "User"
204
+ ```
205
+
206
+ You can pass a constant as well, if the constant is available (note that this
207
+ can cause test performance problems in large Rails applications, since
208
+ referring to the constant will cause it to be eagerly loaded).
209
+
210
+ ```ruby
211
+ factory :access_token, class: User
212
+ ```
213
+
214
+ ### Hash attributes
215
+
125
216
  Because of the block syntax in Ruby, defining attributes as `Hash`es (for
126
217
  serialized/JSON columns, for example) requires two sets of curly brackets:
127
218
 
@@ -131,10 +222,19 @@ factory :program do
131
222
  end
132
223
  ```
133
224
 
134
- It is highly recommended that you have one factory for each class that provides the simplest set of attributes necessary to create an instance of that class. If you're creating ActiveRecord objects, that means that you should only provide attributes that are required through validations and that do not have defaults. Other factories can be created through inheritance to cover common scenarios for each class.
225
+ ### Best practices
226
+
227
+ It is recommended that you have one factory for each class that provides
228
+ the simplest set of attributes necessary to create an instance of that class. If
229
+ you're creating ActiveRecord objects, that means that you should only provide
230
+ attributes that are required through validations and that do not have defaults.
231
+ Other factories can be created through inheritance to cover common scenarios for
232
+ each class.
135
233
 
136
234
  Attempting to define multiple factories with the same name will raise an error.
137
235
 
236
+ ### Definition file paths
237
+
138
238
  Factories can be defined anywhere, but will be automatically loaded after
139
239
  calling `FactoryBot.find_definitions` if factories are defined in files at the
140
240
  following locations:
@@ -144,10 +244,20 @@ following locations:
144
244
  test/factories/*.rb
145
245
  spec/factories/*.rb
146
246
 
247
+ ### Static Attributes
248
+
249
+ Static attributes (without a block) are no longer available in factory\_bot 5.
250
+ You can read more about the decision to remove them in
251
+ [this blog post](https://robots.thoughtbot.com/deprecating-static-attributes-in-factory_bot-4-11).
252
+
253
+
147
254
  Using factories
148
255
  ---------------
149
256
 
150
- factory\_bot supports several different build strategies: build, create, attributes\_for and build\_stubbed:
257
+ ### Build strategies
258
+
259
+ factory\_bot supports several different build strategies: build, create,
260
+ attributes\_for and build\_stubbed:
151
261
 
152
262
  ```ruby
153
263
  # Returns a User instance that's not saved
@@ -168,7 +278,10 @@ create(:user) do |user|
168
278
  end
169
279
  ```
170
280
 
171
- No matter which strategy is used, it's possible to override the defined attributes by passing a hash:
281
+ ### Attribute overrides
282
+
283
+ No matter which strategy is used, it's possible to override the defined
284
+ attributes by passing a hash:
172
285
 
173
286
  ```ruby
174
287
  # Build a User instance and override the first_name property
@@ -177,25 +290,20 @@ user.first_name
177
290
  # => "Joe"
178
291
  ```
179
292
 
180
- Static Attributes
181
- ------------------
182
-
183
- Static attributes, without a block, are deprecated and will be removed in
184
- factory\_bot 5.
185
-
186
- ```ruby
187
- factory :user do
188
- # Do not use deprecated static attributes
189
- admin true
293
+ ### `build_stubbed` and `Marshal.dump`
190
294
 
191
- # Use dynamic attributes instead
192
- admin { true }
193
- end
194
- ```
295
+ Note that objects created with `build_stubbed` cannot be serialized with
296
+ `Marshal.dump`, since factory\_bot defines singleton methods on these objects.
195
297
 
196
298
  Aliases
197
299
  -------
198
- factory_bot allows you to define aliases to existing factories to make them easier to re-use. This could come in handy when, for example, your Post object has an author attribute that actually refers to an instance of a User class. While normally factory_bot can infer the factory name from the association name, in this case it will look for an author factory in vain. So, alias your user factory so it can be used under alias names.
300
+
301
+ factory\_bot allows you to define aliases to existing factories to make them
302
+ easier to re-use. This could come in handy when, for example, your Post object
303
+ has an author attribute that actually refers to an instance of a User class.
304
+ While normally factory\_bot can infer the factory name from the association name,
305
+ in this case it will look for an author factory in vain. So, alias your user
306
+ factory so it can be used under alias names.
199
307
 
200
308
  ```ruby
201
309
  factory :user, aliases: [:author, :commenter] do
@@ -205,17 +313,17 @@ factory :user, aliases: [:author, :commenter] do
205
313
  end
206
314
 
207
315
  factory :post do
208
- author
209
- # instead of
316
+ # The alias allows us to write author instead of
210
317
  # association :author, factory: :user
318
+ author
211
319
  title { "How to read a book effectively" }
212
320
  body { "There are five steps involved." }
213
321
  end
214
322
 
215
323
  factory :comment do
216
- commenter
217
- # instead of
324
+ # The alias allows us to write commenter instead of
218
325
  # association :commenter, factory: :user
326
+ commenter
219
327
  body { "Great article!" }
220
328
  end
221
329
  ```
@@ -239,41 +347,84 @@ create(:user, last_name: "Doe").email
239
347
 
240
348
  Transient Attributes
241
349
  --------------------
350
+ 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.
351
+
352
+ ### With other attributes
242
353
 
243
- There may be times where your code can be DRYed up by passing in transient attributes to factories.
354
+ There may be times where your code can be DRYed up by passing in transient
355
+ attributes to factories. You can access transient attributes within other
356
+ attributes (see [Dependent Attributes](#dependent-attributes)):
244
357
 
245
358
  ```ruby
246
359
  factory :user do
247
360
  transient do
248
361
  rockstar { true }
249
- upcased { false }
250
362
  end
251
363
 
252
364
  name { "John Doe#{" - Rockstar" if rockstar}" }
253
- email { "#{name.downcase}@example.com" }
365
+ end
366
+
367
+ create(:user).name
368
+ #=> "John Doe - ROCKSTAR"
369
+
370
+ create(:user, rockstar: false).name
371
+ #=> "John Doe"
372
+ ```
373
+
374
+ ### With `attributes_for`
375
+
376
+ Transient attributes will be ignored within attributes\_for and won't be set on
377
+ the model, even if the attribute exists or you attempt to override it.
378
+
379
+ ### With callbacks
380
+
381
+ If you need to access the evaluator in a factory\_bot callback,
382
+ you'll need to declare a second block argument (for the evaluator) and access
383
+ transient attributes from there.
384
+
385
+ ```ruby
386
+ factory :user do
387
+ transient do
388
+ upcased { false }
389
+ end
390
+
391
+ name { "John Doe" }
254
392
 
255
393
  after(:create) do |user, evaluator|
256
394
  user.name.upcase! if evaluator.upcased
257
395
  end
258
396
  end
259
397
 
398
+ create(:user).name
399
+ #=> "John Doe"
400
+
260
401
  create(:user, upcased: true).name
261
- #=> "JOHN DOE - ROCKSTAR"
402
+ #=> "JOHN DOE"
262
403
  ```
263
404
 
264
- Static and dynamic attributes can be created as transient attributes. Transient
265
- attributes will be ignored within attributes\_for and won't be set on the model,
266
- even if the attribute exists or you attempt to override it.
405
+ ### With associations
267
406
 
268
- Within factory_bot's dynamic attributes, you can access transient attributes as
269
- you would expect. If you need to access the evaluator in a factory_bot callback,
270
- you'll need to declare a second block argument (for the evaluator) and access
271
- transient attributes from there.
407
+ Transient [associations](#associations) are not supported in factory\_bot.
408
+ Associations within the transient block will be treated as regular,
409
+ non-transient associations.
410
+
411
+ If needed, you can generally work around this by building a factory within a
412
+ transient attribute:
413
+
414
+ ```ruby
415
+ factory :post
416
+
417
+ factory :user do
418
+ transient do
419
+ post { build(:post) }
420
+ end
421
+ end
422
+ ```
272
423
 
273
424
  Method Name / Reserved Word Attributes
274
425
  -------------------------------
275
426
 
276
- If your attributes conflict with existing methods or reserved words you can define them with `add_attribute`.
427
+ If your attributes conflict with existing methods or reserved words (all methods in the [DefinitionProxy](https://github.com/thoughtbot/factory_bot/blob/master/lib/factory_bot/definition_proxy.rb) class) you can define them with `add_attribute`.
277
428
 
278
429
  ```ruby
279
430
  factory :dna do
@@ -289,7 +440,10 @@ end
289
440
  Inheritance
290
441
  -----------
291
442
 
292
- You can easily create multiple factories for the same class without repeating common attributes by nesting factories:
443
+ ### Nested factories
444
+
445
+ You can easily create multiple factories for the same class without repeating
446
+ common attributes by nesting factories:
293
447
 
294
448
  ```ruby
295
449
  factory :post do
@@ -305,6 +459,8 @@ approved_post.title # => "A title"
305
459
  approved_post.approved # => true
306
460
  ```
307
461
 
462
+ ### Assigning parent explicitly
463
+
308
464
  You can also assign the parent explicitly:
309
465
 
310
466
  ```ruby
@@ -317,6 +473,8 @@ factory :approved_post, parent: :post do
317
473
  end
318
474
  ```
319
475
 
476
+ ### Best practices
477
+
320
478
  As mentioned above, it's good practice to define a basic factory for each class
321
479
  with only the attributes required to create it. Then, create more specific
322
480
  factories that inherit from this basic parent. Factory definitions are still
@@ -325,7 +483,10 @@ code, so keep them DRY.
325
483
  Associations
326
484
  ------------
327
485
 
328
- It's possible to set up associations within factories. If the factory name is the same as the association name, the factory name can be left out.
486
+ ### Implicit definition
487
+
488
+ It's possible to set up associations within factories. If the factory name is
489
+ the same as the association name, the factory name can be left out.
329
490
 
330
491
  ```ruby
331
492
  factory :post do
@@ -334,18 +495,146 @@ factory :post do
334
495
  end
335
496
  ```
336
497
 
337
- You can also specify a different factory or override attributes:
498
+ ### Explicit definition
499
+
500
+ You can define associations explicitly. This can be handy especially when
501
+ [Overriding attributes](#overriding-attributes)
338
502
 
339
503
  ```ruby
340
504
  factory :post do
341
505
  # ...
342
- association :author, factory: :user, last_name: "Writely"
506
+ association :author
343
507
  end
344
508
  ```
345
509
 
346
- The behavior of the association method varies depending on the build strategy used for the parent object.
510
+ ### Inline definition
511
+
512
+ You can also define associations inline within regular attributes,
513
+ but note that the value will be `nil`
514
+ when using the `attributes_for` strategy.
347
515
 
348
516
  ```ruby
517
+ factory :post do
518
+ # ...
519
+ author { association :author }
520
+ end
521
+ ```
522
+
523
+ ### Specifying the factory
524
+
525
+ You can specify a different factory (although [Aliases](#aliases) might also
526
+ help you out here).
527
+
528
+ Implicitly:
529
+
530
+ ```ruby
531
+ factory :post do
532
+ # ...
533
+ author factory: :user
534
+ end
535
+ ```
536
+
537
+ Explicitly:
538
+
539
+ ```ruby
540
+ factory :post do
541
+ # ...
542
+ association :author, factory: :user
543
+ end
544
+ ```
545
+
546
+ Inline:
547
+
548
+ ```ruby
549
+ factory :post do
550
+ # ...
551
+ author { association :user }
552
+ end
553
+ ```
554
+
555
+ ### Overriding attributes
556
+
557
+ You can also override attributes.
558
+
559
+ Implicitly:
560
+
561
+ ```ruby
562
+ factory :post do
563
+ # ...
564
+ author factory: :author, last_name: "Writely"
565
+ end
566
+ ```
567
+
568
+ Explicitly:
569
+
570
+
571
+ ```ruby
572
+ factory :post do
573
+ # ...
574
+ association :author, last_name: "Writely"
575
+ end
576
+ ```
577
+
578
+ Or inline using attributes from the factory:
579
+
580
+ ```rb
581
+ factory :post do
582
+ # ...
583
+ author_last_name { "Writely" }
584
+ author { association :author, last_name: author_last_name }
585
+ end
586
+ ```
587
+
588
+ ### Association overrides
589
+
590
+ Attribute overrides can be used to link associated objects:
591
+
592
+ ```ruby
593
+ FactoryBot.define do
594
+ factory :author do
595
+ author_last_name { 'Taylor' }
596
+ end
597
+
598
+ factory :post do
599
+ author
600
+ end
601
+ end
602
+
603
+ eunji = build(:author, name: 'Eunji')
604
+ post = build(:post, author: eunji)
605
+ ```
606
+
607
+ ### Build strategies
608
+
609
+ In factory\_bot 5, associations default to using the same build strategy as
610
+ their parent object:
611
+
612
+ ```ruby
613
+ FactoryBot.define do
614
+ factory :author
615
+
616
+ factory :post do
617
+ author
618
+ end
619
+ end
620
+
621
+ post = build(:post)
622
+ post.new_record? # => true
623
+ post.author.new_record? # => true
624
+
625
+ post = create(:post)
626
+ post.new_record? # => false
627
+ post.author.new_record? # => false
628
+ ```
629
+
630
+ This is different than the default behavior for previous versions of
631
+ factory\_bot, where the association strategy would not always match the strategy
632
+ of the parent object. If you want to continue using the old behavior, you can
633
+ set the `use_parent_strategy` configuration option to `false`.
634
+
635
+ ```ruby
636
+ FactoryBot.use_parent_strategy = false
637
+
349
638
  # Builds and saves a User and a Post
350
639
  post = create(:post)
351
640
  post.new_record? # => false
@@ -357,9 +646,11 @@ post.new_record? # => true
357
646
  post.author.new_record? # => false
358
647
  ```
359
648
 
360
- To not save the associated object, specify strategy: :build in the factory:
649
+ To not save the associated object, specify `strategy: :build` in the factory:
361
650
 
362
651
  ```ruby
652
+ FactoryBot.use_parent_strategy = false
653
+
363
654
  factory :post do
364
655
  # ...
365
656
  association :author, factory: :user, strategy: :build
@@ -380,27 +671,53 @@ factory :post do
380
671
  author strategy: :build # <<< this does *not* work; causes author_id to be nil
381
672
  ```
382
673
 
383
- Generating data for a `has_many` relationship is a bit more involved,
384
- depending on the amount of flexibility desired, but here's a surefire example
385
- of generating associated data.
674
+ ### `has_many` associations
675
+
676
+ There are a few ways to generate data for a `has_many` relationship. The
677
+ simplest approach is to write a helper method in plain Ruby to tie together the
678
+ different records:
386
679
 
387
680
  ```ruby
388
681
  FactoryBot.define do
682
+ factory :post do
683
+ title { "Through the Looking Glass" }
684
+ user
685
+ end
686
+
687
+ factory :user do
688
+ name { "Rachel Sanchez" }
689
+ end
690
+ end
691
+
692
+ def user_with_posts(posts_count: 5)
693
+ FactoryBot.create(:user) do |user|
694
+ FactoryBot.create_list(:post, posts_count, user: user)
695
+ end
696
+ end
389
697
 
390
- # post factory with a `belongs_to` association for the user
698
+ create(:user).posts.length # 0
699
+ user_with_posts.posts.length # 5
700
+ user_with_posts(posts_count: 15).posts.length # 15
701
+ ```
702
+
703
+ If you prefer to keep the object creation fully within factory\_bot, you can
704
+ build the posts in an `after(:create)` callback.
705
+
706
+
707
+ ```ruby
708
+ FactoryBot.define do
391
709
  factory :post do
392
710
  title { "Through the Looking Glass" }
393
711
  user
394
712
  end
395
713
 
396
- # user factory without associated posts
397
714
  factory :user do
398
715
  name { "John Doe" }
399
716
 
400
717
  # user_with_posts will create post data after the user has been created
401
718
  factory :user_with_posts do
402
- # posts_count is declared as a transient attribute and available in
403
- # attributes on the factory, as well as the callback via the evaluator
719
+ # posts_count is declared as a transient attribute available in the
720
+ # callback via the evaluator
404
721
  transient do
405
722
  posts_count { 5 }
406
723
  end
@@ -411,58 +728,142 @@ FactoryBot.define do
411
728
  # to create and we make sure the user is associated properly to the post
412
729
  after(:create) do |user, evaluator|
413
730
  create_list(:post, evaluator.posts_count, user: user)
731
+
732
+ # You may need to reload the record here, depending on your application
733
+ user.reload
414
734
  end
415
735
  end
416
736
  end
417
737
  end
738
+
739
+ create(:user).posts.length # 0
740
+ create(:user_with_posts).posts.length # 5
741
+ create(:user_with_posts, posts_count: 15).posts.length # 15
418
742
  ```
419
743
 
420
- This allows us to do:
744
+ Or, for a solution that works with `build`, `build_stubbed`, and `create`
745
+ (although it doesn't work well with `attributes_for`), you can use inline
746
+ associations:
421
747
 
422
748
  ```ruby
749
+ FactoryBot.define do
750
+ factory :post do
751
+ title { "Through the Looking Glass" }
752
+ user
753
+ end
754
+
755
+ factory :user do
756
+ name { "Taylor Kim" }
757
+
758
+ factory :user_with_posts do
759
+ posts { [association(:post)] }
760
+ end
761
+ end
762
+ end
763
+
423
764
  create(:user).posts.length # 0
765
+ create(:user_with_posts).posts.length # 1
766
+ build(:user_with_posts).posts.length # 1
767
+ build_stubbed(:user_with_posts).posts.length # 1
768
+ ```
769
+
770
+ For more flexibility you can combine this with the `posts_count` transient
771
+ attribute from the callback example:
772
+
773
+ ```ruby
774
+ FactoryBot.define do
775
+ factory :post do
776
+ title { "Through the Looking Glass" }
777
+ user
778
+ end
779
+
780
+ factory :user do
781
+ name { "Adiza Kumato" }
782
+
783
+ factory :user_with_posts do
784
+ transient do
785
+ posts_count { 5 }
786
+ end
787
+
788
+ posts do
789
+ Array.new(posts_count) { association(:post) }
790
+ end
791
+ end
792
+ end
793
+ end
794
+
424
795
  create(:user_with_posts).posts.length # 5
425
796
  create(:user_with_posts, posts_count: 15).posts.length # 15
797
+ build(:user_with_posts, posts_count: 15).posts.length # 15
798
+ build_stubbed(:user_with_posts, posts_count: 15).posts.length # 15
426
799
  ```
427
800
 
801
+ ### `has_and_belongs_to_many` associations
802
+
428
803
  Generating data for a `has_and_belongs_to_many` relationship is very similar
429
- to the above `has_many` relationship, with a small change, you need to pass an
804
+ to the above `has_many` relationship, with a small change: you need to pass an
430
805
  array of objects to the model's pluralized attribute name rather than a single
431
806
  object to the singular version of the attribute name.
432
807
 
433
- Here's an example with two models that are related via
434
- `has_and_belongs_to_many`:
435
808
 
436
809
  ```ruby
437
- FactoryBot.define do
810
+ def profile_with_languages(languages_count: 2)
811
+ FactoryBot.create(:profile) do |profile|
812
+ FactoryBot.create_list(:language, languages_count, profiles: [profile])
813
+ end
814
+ end
815
+ ```
438
816
 
439
- # language factory with a `belongs_to` association for the profile
440
- factory :language do
441
- title { "Through the Looking Glass" }
442
- profile
817
+ Or with the callback approach:
818
+
819
+ ```ruby
820
+ factory :profile_with_languages do
821
+ transient do
822
+ languages_count { 2 }
443
823
  end
444
824
 
445
- # profile factory without associated languages
446
- factory :profile do
447
- name { "John Doe" }
825
+ after(:create) do |profile, evaluator|
826
+ create_list(:language, evaluator.languages_count, profiles: [profile])
827
+ profile.reload
828
+ end
829
+ end
830
+ ```
448
831
 
449
- # profile_with_languages will create language data after the profile has
450
- # been created
451
- factory :profile_with_languages do
452
- # languages_count is declared as an ignored attribute and available in
453
- # attributes on the factory, as well as the callback via the evaluator
454
- transient do
455
- languages_count { 5 }
456
- end
832
+ Or the inline association approach (note the use of the `instance` method here
833
+ to refer to the profile being built):
457
834
 
458
- # the after(:create) yields two values; the profile instance itself and
459
- # the evaluator, which stores all values from the factory, including
460
- # ignored attributes; `create_list`'s second argument is the number of
461
- # records to create and we make sure the profile is associated properly
462
- # to the language
463
- after(:create) do |profile, evaluator|
464
- create_list(:language, evaluator.languages_count, profiles: [profile])
465
- end
835
+ ```ruby
836
+ factory :profile_with_languages do
837
+ transient do
838
+ languages_count { 2 }
839
+ end
840
+
841
+ languages do
842
+ Array.new(languages_count) do
843
+ association(:language, profiles: [instance])
844
+ end
845
+ end
846
+ end
847
+ ```
848
+
849
+ ### Polymorphic associations
850
+
851
+ Polymorphic associations can be handled with traits:
852
+
853
+ ```ruby
854
+ FactoryBot.define do
855
+ factory :video
856
+ factory :photo
857
+
858
+ factory :comment do
859
+ for_photo # default to the :for_photo trait if none is specified
860
+
861
+ trait :for_video do
862
+ association :commentable, factory: :video
863
+ end
864
+
865
+ trait :for_photo do
866
+ association :commentable, factory: :photo
466
867
  end
467
868
  end
468
869
  end
@@ -471,14 +872,72 @@ end
471
872
  This allows us to do:
472
873
 
473
874
  ```ruby
474
- create(:profile).languages.length # 0
475
- create(:profile_with_languages).languages.length # 5
476
- create(:profile_with_languages, languages_count: 15).languages.length # 15
875
+ create(:comment)
876
+ create(:comment, :for_video)
877
+ create(:comment, :for_photo)
878
+ ```
879
+
880
+ ### Interconnected associations
881
+
882
+ There are limitless ways objects might be interconnected, and
883
+ factory\_bot may not always be suited to handle those relationships. In some
884
+ cases it makes sense to use factory\_bot to build each individual object, and
885
+ then to write helper methods in plain Ruby to tie those objects together.
886
+
887
+ That said, some more complex, interconnected relationships can be built in factory\_bot
888
+ using inline associations with reference to the `instance` being built.
889
+
890
+ Let's say your models look like this, where an associated `Student` and
891
+ `Profile` should both belong to the same `School`:
892
+
893
+ ```ruby
894
+ class Student < ApplicationRecord
895
+ belongs_to :school
896
+ has_one :profile
897
+ end
898
+
899
+ class Profile < ApplicationRecord
900
+ belongs_to :school
901
+ belongs_to :student
902
+ end
903
+
904
+ class School < ApplicationRecord
905
+ has_many :students
906
+ has_many :profiles
907
+ end
908
+ ```
909
+
910
+ We can ensure the student and profile are connected to each other and to the
911
+ same school with a factory like this:
912
+
913
+ ```ruby
914
+ FactoryBot.define do
915
+ factory :student do
916
+ school
917
+ profile { association :profile, student: instance, school: school }
918
+ end
919
+
920
+ factory :profile do
921
+ school
922
+ student { association :student, profile: instance, school: school }
923
+ end
924
+
925
+ factory :school
926
+ end
477
927
  ```
478
928
 
929
+ Note that this approach works with `build`, `build_stubbed`, and `create`, but
930
+ the associations will return `nil` when using `attributes_for`.
931
+
932
+ Also, note that if you assign any attributes inside a custom `initialize_with`
933
+ (e.g. `initialize_with { new(**attributes) }`), those attributes should not refer to `instance`,
934
+ since it will be `nil`.
935
+
479
936
  Sequences
480
937
  ---------
481
938
 
939
+ ### Global sequences
940
+
482
941
  Unique values in a specific format (for example, e-mail addresses) can be
483
942
  generated using sequences. Sequences are defined by calling `sequence` in a
484
943
  definition block, and values in a sequence are generated by calling
@@ -499,6 +958,8 @@ generate :email
499
958
  # => "person2@example.com"
500
959
  ```
501
960
 
961
+ ### With dynamic attributes
962
+
502
963
  Sequences can be used in dynamic attributes:
503
964
 
504
965
  ```ruby
@@ -507,6 +968,8 @@ factory :invite do
507
968
  end
508
969
  ```
509
970
 
971
+ ### As implicit attributes
972
+
510
973
  Or as implicit attributes:
511
974
 
512
975
  ```ruby
@@ -515,6 +978,11 @@ factory :user do
515
978
  end
516
979
  ```
517
980
 
981
+ Note that defining sequences as implicit attributes will not work if you have a
982
+ factory with the same name as the sequence.
983
+
984
+ ### Inline sequences
985
+
518
986
  And it's also possible to define an in-line sequence that is only used in
519
987
  a particular factory:
520
988
 
@@ -524,7 +992,10 @@ factory :user do
524
992
  end
525
993
  ```
526
994
 
527
- You can also override the initial value:
995
+ ### Initial value
996
+
997
+ You can override the initial value. Any value that responds to the `#next`
998
+ method will work (e.g. 1, 2, 3, 'a', 'b', 'c')
528
999
 
529
1000
  ```ruby
530
1001
  factory :user do
@@ -532,6 +1003,8 @@ factory :user do
532
1003
  end
533
1004
  ```
534
1005
 
1006
+ ### Without a block
1007
+
535
1008
  Without a block, the value will increment itself, starting at its initial value:
536
1009
 
537
1010
  ```ruby
@@ -540,6 +1013,8 @@ factory :post do
540
1013
  end
541
1014
  ```
542
1015
 
1016
+ ### Aliases
1017
+
543
1018
  Sequences can also have aliases. The sequence aliases share the same counter:
544
1019
 
545
1020
  ```ruby
@@ -569,6 +1044,8 @@ end
569
1044
 
570
1045
  The value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.
571
1046
 
1047
+ ### Rewinding
1048
+
572
1049
  Sequences can also be rewound with `FactoryBot.rewind_sequences`:
573
1050
 
574
1051
  ```ruby
@@ -585,9 +1062,27 @@ generate(:email) # "person1@example.com"
585
1062
 
586
1063
  This rewinds all registered sequences.
587
1064
 
1065
+ ### Uniqueness
1066
+
1067
+ When working with uniqueness constraints, be careful not to pass in override values that will conflict with the generated sequence values.
1068
+
1069
+ In this example the email will be the same for both users. If email must be unique, this code will error:
1070
+
1071
+ ```rb
1072
+ factory :user do
1073
+ sequence(:email) { |n| "person#{n}@example.com" }
1074
+ end
1075
+
1076
+ FactoryBot.create(:user, email: "person1@example.com")
1077
+ FactoryBot.create(:user)
1078
+ ```
1079
+
1080
+
588
1081
  Traits
589
1082
  ------
590
1083
 
1084
+ ### Defining traits
1085
+
591
1086
  Traits allow you to group attributes together and then apply them
592
1087
  to any factory.
593
1088
 
@@ -623,7 +1118,9 @@ factory :story do
623
1118
  end
624
1119
  ```
625
1120
 
626
- Traits can be used as attributes:
1121
+ ### As implicit attributes
1122
+
1123
+ Traits can be used as implicit attributes:
627
1124
 
628
1125
  ```ruby
629
1126
  factory :week_long_published_story_with_title, parent: :story do
@@ -633,6 +1130,11 @@ factory :week_long_published_story_with_title, parent: :story do
633
1130
  end
634
1131
  ```
635
1132
 
1133
+ Note that defining traits as implicit attributes will not work if you have a
1134
+ factory or sequence with the same name as the trait.
1135
+
1136
+ ### Attribute precedence
1137
+
636
1138
  Traits that define the same attributes won't raise AttributeDefinitionErrors;
637
1139
  the trait that defines the attribute latest gets precedence.
638
1140
 
@@ -641,16 +1143,16 @@ factory :user do
641
1143
  name { "Friendly User" }
642
1144
  login { name }
643
1145
 
644
- trait :male do
1146
+ trait :active do
645
1147
  name { "John Doe" }
646
- gender { "Male" }
647
- login { "#{name} (M)" }
1148
+ status { :active }
1149
+ login { "#{name} (active)" }
648
1150
  end
649
1151
 
650
- trait :female do
1152
+ trait :inactive do
651
1153
  name { "Jane Doe" }
652
- gender { "Female" }
653
- login { "#{name} (F)" }
1154
+ status { :inactive }
1155
+ login { "#{name} (inactive)" }
654
1156
  end
655
1157
 
656
1158
  trait :admin do
@@ -658,40 +1160,45 @@ factory :user do
658
1160
  login { "admin-#{name}" }
659
1161
  end
660
1162
 
661
- factory :male_admin, traits: [:male, :admin] # login will be "admin-John Doe"
662
- factory :female_admin, traits: [:admin, :female] # login will be "Jane Doe (F)"
1163
+ factory :active_admin, traits: [:active, :admin] # login will be "admin-John Doe"
1164
+ factory :inactive_admin, traits: [:admin, :inactive] # login will be "Jane Doe (inactive)"
663
1165
  end
664
1166
  ```
665
1167
 
666
- You can also override individual attributes granted by a trait in subclasses.
1168
+ ### In child factories
1169
+
1170
+ You can override individual attributes granted by a trait in a child factory:
667
1171
 
668
1172
  ```ruby
669
1173
  factory :user do
670
1174
  name { "Friendly User" }
671
1175
  login { name }
672
1176
 
673
- trait :male do
1177
+ trait :active do
674
1178
  name { "John Doe" }
675
- gender { "Male" }
1179
+ status { :active }
676
1180
  login { "#{name} (M)" }
677
1181
  end
678
1182
 
679
1183
  factory :brandon do
680
- male
1184
+ active
681
1185
  name { "Brandon" }
682
1186
  end
683
1187
  end
684
1188
  ```
685
1189
 
686
- Traits can also be passed in as a list of symbols when you construct an instance from factory_bot.
1190
+ ### Using traits
1191
+
1192
+ Traits can also be passed in as a list of symbols when you construct an instance
1193
+ from factory\_bot.
687
1194
 
688
1195
  ```ruby
689
1196
  factory :user do
690
1197
  name { "Friendly User" }
691
1198
 
692
- trait :male do
1199
+ trait :active do
693
1200
  name { "John Doe" }
694
- gender { "Male" }
1201
+ status { :active }
695
1202
  end
696
1203
 
697
1204
  trait :admin do
@@ -699,8 +1206,8 @@ factory :user do
699
1206
  end
700
1207
  end
701
1208
 
702
- # creates an admin user with gender "Male" and name "Jon Snow"
703
- create(:user, :admin, :male, name: "Jon Snow")
1209
+ # creates an admin user with :active status and name "Jon Snow"
1210
+ create(:user, :admin, :active, name: "Jon Snow")
704
1211
  ```
705
1212
 
706
1213
  This ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.
@@ -718,10 +1225,12 @@ factory :user do
718
1225
  end
719
1226
  end
720
1227
 
721
- # creates 3 admin users with gender "Male" and name "Jon Snow"
722
- create_list(:user, 3, :admin, :male, name: "Jon Snow")
1228
+ # creates 3 admin users with :active status and name "Jon Snow"
1229
+ create_list(:user, 3, :admin, :active, name: "Jon Snow")
723
1230
  ```
724
1231
 
1232
+ ### With associations
1233
+
725
1234
  Traits can be used with associations easily too:
726
1235
 
727
1236
  ```ruby
@@ -762,6 +1271,8 @@ end
762
1271
  create(:post).author
763
1272
  ```
764
1273
 
1274
+ ### Traits within traits
1275
+
765
1276
  Traits can be used within other traits to mix in their attributes.
766
1277
 
767
1278
  ```ruby
@@ -777,6 +1288,8 @@ factory :order do
777
1288
  end
778
1289
  ```
779
1290
 
1291
+ ### With transient attributes
1292
+
780
1293
  Finally, traits can accept transient attributes.
781
1294
 
782
1295
  ```ruby
@@ -795,9 +1308,103 @@ end
795
1308
  create :invoice, :with_amount, amount: 2
796
1309
  ```
797
1310
 
1311
+ ### Enum traits
1312
+
1313
+ Given an Active Record model with an enum attribute:
1314
+
1315
+ ```rb
1316
+ class Task < ActiveRecord::Base
1317
+ enum status: {queued: 0, started: 1, finished: 2}
1318
+ end
1319
+
1320
+ ```
1321
+
1322
+ factory\_bot will automatically define traits for each possible value of the
1323
+ enum:
1324
+
1325
+ ```rb
1326
+ FactoryBot.define do
1327
+ factory :task
1328
+ end
1329
+
1330
+ FactoryBot.build(:task, :queued)
1331
+ FactoryBot.build(:task, :started)
1332
+ FactoryBot.build(:task, :finished)
1333
+ ```
1334
+
1335
+ Writing the traits out manually would be cumbersome, and is not necessary:
1336
+
1337
+ ```rb
1338
+ FactoryBot.define do
1339
+ factory :task do
1340
+ trait :queued do
1341
+ status { :queued }
1342
+ end
1343
+
1344
+ trait :started do
1345
+ status { :started }
1346
+ end
1347
+
1348
+ trait :finished do
1349
+ status { :finished }
1350
+ end
1351
+ end
1352
+ end
1353
+ ```
1354
+
1355
+ If automatically defining traits for enum attributes on every factory is not
1356
+ desired, it is possible to disable the feature by setting
1357
+ `FactoryBot.automatically_define_enum_traits = false`
1358
+
1359
+ In that case, it is still possible to explicitly define traits for an enum
1360
+ attribute in a particular factory:
1361
+
1362
+ ```rb
1363
+ FactoryBot.automatically_define_enum_traits = false
1364
+
1365
+ FactoryBot.define do
1366
+ factory :task do
1367
+ traits_for_enum(:status)
1368
+ end
1369
+ end
1370
+ ```
1371
+
1372
+ It is also possible to use this feature for other enumerable values, not
1373
+ specifically tied to Active Record enum attributes.
1374
+
1375
+ With an array:
1376
+
1377
+ ```rb
1378
+ class Task
1379
+ attr_accessor :status
1380
+ end
1381
+
1382
+ FactoryBot.define do
1383
+ factory :task do
1384
+ traits_for_enum(:status, ["queued", "started", "finished"])
1385
+ end
1386
+ end
1387
+ ```
1388
+
1389
+ Or with a hash:
1390
+
1391
+ ```rb
1392
+ class Task
1393
+ attr_accessor :status
1394
+ end
1395
+
1396
+ FactoryBot.define do
1397
+ factory :task do
1398
+ traits_for_enum(:status, { queued: 0, started: 1, finished: 2 })
1399
+ end
1400
+ end
1401
+ ```
1402
+
798
1403
  Callbacks
799
1404
  ---------
800
1405
 
1406
+ ### Default callbacks
1407
+
801
1408
  factory\_bot makes available four callbacks for injecting some code:
802
1409
 
803
1410
  * after(:build) - called after a factory is built (via `FactoryBot.build`, `FactoryBot.create`)
@@ -816,6 +1423,8 @@ end
816
1423
 
817
1424
  Note that you'll have an instance of the user in the block. This can be useful.
818
1425
 
1426
+ ### Multiple callbacks
1427
+
819
1428
  You can also define multiple types of callbacks on the same factory:
820
1429
 
821
1430
  ```ruby
@@ -825,7 +1434,8 @@ factory :user do
825
1434
  end
826
1435
  ```
827
1436
 
828
- Factories can also define any number of the same kind of callback. These callbacks will be executed in the order they are specified:
1437
+ Factories can also define any number of the same kind of callback. These
1438
+ callbacks will be executed in the order they are specified:
829
1439
 
830
1440
  ```ruby
831
1441
  factory :user do
@@ -836,9 +1446,12 @@ end
836
1446
 
837
1447
  Calling `create` will invoke both `after_build` and `after_create` callbacks.
838
1448
 
839
- Also, like standard attributes, child factories will inherit (and can also define) callbacks from their parent factory.
1449
+ Also, like standard attributes, child factories will inherit (and can also
1450
+ define) callbacks from their parent factory.
840
1451
 
841
- Multiple callbacks can be assigned to run a block; this is useful when building various strategies that run the same code (since there are no callbacks that are shared across all strategies).
1452
+ Multiple callbacks can be assigned to run a block; this is useful when building
1453
+ various strategies that run the same code (since there are no callbacks that are
1454
+ shared across all strategies).
842
1455
 
843
1456
  ```ruby
844
1457
  factory :user do
@@ -848,6 +1461,8 @@ factory :user do
848
1461
  end
849
1462
  ```
850
1463
 
1464
+ ### Global callbacks
1465
+
851
1466
  To override callbacks for all factories, define them within the
852
1467
  `FactoryBot.define` block:
853
1468
 
@@ -862,7 +1477,9 @@ FactoryBot.define do
862
1477
  end
863
1478
  ```
864
1479
 
865
- You can also call callbacks that rely on `Symbol#to_proc`:
1480
+ ### Symbol#to_proc
1481
+
1482
+ You can call callbacks that rely on `Symbol#to_proc`:
866
1483
 
867
1484
  ```ruby
868
1485
  # app/models/user.rb
@@ -885,15 +1502,16 @@ create(:user) # creates the user and confirms it
885
1502
  Modifying factories
886
1503
  -------------------
887
1504
 
888
- If you're given a set of factories (say, from a gem developer) but want to change them to fit into your application better, you can
889
- modify that factory instead of creating a child factory and adding attributes there.
1505
+ If you're given a set of factories (say, from a gem developer) but want to
1506
+ change them to fit into your application better, you can modify that factory
1507
+ instead of creating a child factory and adding attributes there.
890
1508
 
891
1509
  If a gem were to give you a User factory:
892
1510
 
893
1511
  ```ruby
894
1512
  FactoryBot.define do
895
1513
  factory :user do
896
- full_name "John Doe"
1514
+ full_name { "John Doe" }
897
1515
  sequence(:username) { |n| "user#{n}" }
898
1516
  password { "password" }
899
1517
  end
@@ -907,7 +1525,6 @@ FactoryBot.define do
907
1525
  factory :application_user, parent: :user do
908
1526
  full_name { "Jane Doe" }
909
1527
  date_of_birth { 21.years.ago }
910
- gender { "Female" }
911
1528
  health { 90 }
912
1529
  end
913
1530
  end
@@ -920,7 +1537,6 @@ FactoryBot.modify do
920
1537
  factory :user do
921
1538
  full_name { "Jane Doe" }
922
1539
  date_of_birth { 21.years.ago }
923
- gender { "Female" }
924
1540
  health { 90 }
925
1541
  end
926
1542
  end
@@ -950,6 +1566,14 @@ To set the attributes for each of the factories, you can pass in a hash as you n
950
1566
  twenty_year_olds = build_list(:user, 25, date_of_birth: 20.years.ago)
951
1567
  ```
952
1568
 
1569
+ In order to set different attributes for each factory, these methods may be passed a block, with the factory and the index as parameters:
1570
+
1571
+ ```ruby
1572
+ twenty_somethings = build_list(:user, 10) do |user, i|
1573
+ user.date_of_birth = (20 + i).years.ago
1574
+ end
1575
+ ```
1576
+
953
1577
  `build_stubbed_list` will give you fully stubbed out instances:
954
1578
 
955
1579
  ```ruby
@@ -972,7 +1596,7 @@ users_attrs = attributes_for_list(:user, 25) # array of attribute hashes
972
1596
  Linting Factories
973
1597
  -----------------
974
1598
 
975
- factory_bot allows for linting known factories:
1599
+ factory\_bot allows for linting known factories:
976
1600
 
977
1601
  ```ruby
978
1602
  FactoryBot.lint
@@ -999,8 +1623,10 @@ namespace :factory_bot do
999
1623
  desc "Verify that all FactoryBot factories are valid"
1000
1624
  task lint: :environment do
1001
1625
  if Rails.env.test?
1002
- DatabaseCleaner.cleaning do
1626
+ conn = ActiveRecord::Base.connection
1627
+ conn.transaction do
1003
1628
  FactoryBot.lint
1629
+ raise ActiveRecord::Rollback
1004
1630
  end
1005
1631
  else
1006
1632
  system("bundle exec rake factory_bot:lint RAILS_ENV='test'")
@@ -1012,8 +1638,7 @@ end
1012
1638
 
1013
1639
  After calling `FactoryBot.lint`, you'll likely want to clear out the
1014
1640
  database, as records will most likely be created. The provided example above
1015
- uses the database_cleaner gem to clear out the database; be sure to add the
1016
- gem to your Gemfile under the appropriate groups.
1641
+ uses an sql transaction and rollback to leave the database clean.
1017
1642
 
1018
1643
  You can lint factories selectively by passing only factories you want linted:
1019
1644
 
@@ -1047,10 +1672,17 @@ You can also specify the strategy used for linting:
1047
1672
  FactoryBot.lint strategy: :build
1048
1673
  ```
1049
1674
 
1675
+ Verbose linting will include full backtraces for each error, which can be
1676
+ helpful for debugging:
1677
+
1678
+ ```ruby
1679
+ FactoryBot.lint verbose: true
1680
+ ```
1681
+
1050
1682
  Custom Construction
1051
1683
  -------------------
1052
1684
 
1053
- If you want to use factory_bot to construct an object where some attributes
1685
+ If you want to use factory\_bot to construct an object where some attributes
1054
1686
  are passed to `initialize` or if you want to do something other than simply
1055
1687
  calling `new` on your build class, you can override the default behavior by
1056
1688
  defining `initialize_with` on your factory. Example:
@@ -1078,7 +1710,7 @@ end
1078
1710
  build(:user).name # Jane Doe
1079
1711
  ```
1080
1712
 
1081
- Although factory_bot is written to work with ActiveRecord out of the box, it
1713
+ Although factory\_bot is written to work with ActiveRecord out of the box, it
1082
1714
  can also work with any Ruby class. For maximum compatibility with ActiveRecord,
1083
1715
  the default initializer builds all instances by calling `new` on your build class
1084
1716
  without any arguments. It then calls attribute writer methods to assign all the
@@ -1089,7 +1721,7 @@ You can override the initializer in order to:
1089
1721
 
1090
1722
  * Build non-ActiveRecord objects that require arguments to `initialize`
1091
1723
  * Use a method other than `new` to instantiate the instance
1092
- * Do crazy things like decorate the instance after it's built
1724
+ * Do wild things like decorate the instance after it's built
1093
1725
 
1094
1726
  When using `initialize_with`, you don't have to declare the class itself when
1095
1727
  calling `new`; however, any other class methods you want to call will have to
@@ -1116,7 +1748,7 @@ factory :user do
1116
1748
 
1117
1749
  name "John Doe"
1118
1750
 
1119
- initialize_with { new(attributes) }
1751
+ initialize_with { new(**attributes) }
1120
1752
  end
1121
1753
  ```
1122
1754
 
@@ -1151,7 +1783,7 @@ build(:user)
1151
1783
  User.new('value')
1152
1784
  ```
1153
1785
 
1154
- This prevents duplicate assignment; in versions of factory_bot before 4.0, it
1786
+ This prevents duplicate assignment; in versions of factory\_bot before 4.0, it
1155
1787
  would run this:
1156
1788
 
1157
1789
  ```ruby
@@ -1337,12 +1969,12 @@ with associations, as below:
1337
1969
 
1338
1970
  ```ruby
1339
1971
  FactoryBot.define do
1340
- factory :united_states, class: Location do
1972
+ factory :united_states, class: "Location" do
1341
1973
  name { 'United States' }
1342
1974
  association :location_group, factory: :north_america
1343
1975
  end
1344
1976
 
1345
- factory :north_america, class: LocationGroup do
1977
+ factory :north_america, class: "LocationGroup" do
1346
1978
  name { 'North America' }
1347
1979
  end
1348
1980
  end