factory_bot 4.11.1 → 6.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +58 -13
  3. data/GETTING_STARTED.md +825 -153
  4. data/LICENSE +1 -1
  5. data/NEWS.md +385 -0
  6. data/README.md +20 -30
  7. data/lib/factory_bot/aliases.rb +3 -3
  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 +27 -12
  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/attributes_for.rb +4 -0
  42. data/lib/factory_bot/strategy/build.rb +4 -0
  43. data/lib/factory_bot/strategy/create.rb +4 -0
  44. data/lib/factory_bot/strategy/null.rb +4 -0
  45. data/lib/factory_bot/strategy/stub.rb +41 -32
  46. data/lib/factory_bot/strategy_calculator.rb +1 -1
  47. data/lib/factory_bot/strategy_syntax_method_registrar.rb +13 -2
  48. data/lib/factory_bot/syntax/default.rb +13 -25
  49. data/lib/factory_bot/syntax/methods.rb +32 -9
  50. data/lib/factory_bot/syntax.rb +2 -2
  51. data/lib/factory_bot/trait.rb +7 -4
  52. data/lib/factory_bot/version.rb +1 -1
  53. data/lib/factory_bot.rb +71 -140
  54. metadata +46 -34
  55. data/NEWS +0 -306
  56. data/lib/factory_bot/attribute/static.rb +0 -16
  57. data/lib/factory_bot/declaration/static.rb +0 -26
  58. 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"
99
+ gem "factory_bot"
17
100
  ```
18
101
 
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:
102
+ ### Configure your test suite
21
103
 
22
- ```bash
23
- export JRUBY_OPTS=--1.9
24
- ```
104
+ #### RSpec
25
105
 
26
- Once your Gemfile is updated, you'll want to update your bundle.
27
-
28
- Configure your test suite
29
- -------------------------
30
-
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
- ------------------
293
+ ### `build_stubbed` and `Marshal.dump`
182
294
 
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
190
-
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.
242
351
 
243
- There may be times where your code can be DRYed up by passing in transient attributes to factories.
352
+ ### With other attributes
353
+
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)
502
+
503
+ ```ruby
504
+ factory :post do
505
+ # ...
506
+ association :author
507
+ end
508
+ ```
509
+
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.
515
+
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:
338
529
 
339
530
  ```ruby
340
531
  factory :post do
341
532
  # ...
342
- association :author, factory: :user, last_name: "Writely"
533
+ author factory: :user
343
534
  end
344
535
  ```
345
536
 
346
- The behavior of the association method varies depending on the build strategy used for the parent object.
537
+ Explicitly:
347
538
 
348
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
+ 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
389
691
 
390
- # post factory with a `belongs_to` association for the user
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
697
+
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)
477
878
  ```
478
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
927
+ ```
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,17 @@ factory :post do
540
1013
  end
541
1014
  ```
542
1015
 
1016
+ Please note, that the value for the sequence could be any Enumerable instance,
1017
+ as long as it responds to `#next`:
1018
+
1019
+ ```ruby
1020
+ factory :task do
1021
+ sequence :priority, %i[low medium high urgent].cycle
1022
+ end
1023
+ ```
1024
+
1025
+ ### Aliases
1026
+
543
1027
  Sequences can also have aliases. The sequence aliases share the same counter:
544
1028
 
545
1029
  ```ruby
@@ -569,6 +1053,8 @@ end
569
1053
 
570
1054
  The value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.
571
1055
 
1056
+ ### Rewinding
1057
+
572
1058
  Sequences can also be rewound with `FactoryBot.rewind_sequences`:
573
1059
 
574
1060
  ```ruby
@@ -585,9 +1071,27 @@ generate(:email) # "person1@example.com"
585
1071
 
586
1072
  This rewinds all registered sequences.
587
1073
 
1074
+ ### Uniqueness
1075
+
1076
+ When working with uniqueness constraints, be careful not to pass in override values that will conflict with the generated sequence values.
1077
+
1078
+ In this example the email will be the same for both users. If email must be unique, this code will error:
1079
+
1080
+ ```rb
1081
+ factory :user do
1082
+ sequence(:email) { |n| "person#{n}@example.com" }
1083
+ end
1084
+
1085
+ FactoryBot.create(:user, email: "person1@example.com")
1086
+ FactoryBot.create(:user)
1087
+ ```
1088
+
1089
+
588
1090
  Traits
589
1091
  ------
590
1092
 
1093
+ ### Defining traits
1094
+
591
1095
  Traits allow you to group attributes together and then apply them
592
1096
  to any factory.
593
1097
 
@@ -623,7 +1127,9 @@ factory :story do
623
1127
  end
624
1128
  ```
625
1129
 
626
- Traits can be used as attributes:
1130
+ ### As implicit attributes
1131
+
1132
+ Traits can be used as implicit attributes:
627
1133
 
628
1134
  ```ruby
629
1135
  factory :week_long_published_story_with_title, parent: :story do
@@ -633,6 +1139,11 @@ factory :week_long_published_story_with_title, parent: :story do
633
1139
  end
634
1140
  ```
635
1141
 
1142
+ Note that defining traits as implicit attributes will not work if you have a
1143
+ factory or sequence with the same name as the trait.
1144
+
1145
+ ### Attribute precedence
1146
+
636
1147
  Traits that define the same attributes won't raise AttributeDefinitionErrors;
637
1148
  the trait that defines the attribute latest gets precedence.
638
1149
 
@@ -641,16 +1152,16 @@ factory :user do
641
1152
  name { "Friendly User" }
642
1153
  login { name }
643
1154
 
644
- trait :male do
1155
+ trait :active do
645
1156
  name { "John Doe" }
646
- gender { "Male" }
647
- login { "#{name} (M)" }
1157
+ status { :active }
1158
+ login { "#{name} (active)" }
648
1159
  end
649
1160
 
650
- trait :female do
1161
+ trait :inactive do
651
1162
  name { "Jane Doe" }
652
- gender { "Female" }
653
- login { "#{name} (F)" }
1163
+ status { :inactive }
1164
+ login { "#{name} (inactive)" }
654
1165
  end
655
1166
 
656
1167
  trait :admin do
@@ -658,40 +1169,67 @@ factory :user do
658
1169
  login { "admin-#{name}" }
659
1170
  end
660
1171
 
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)"
1172
+ factory :active_admin, traits: [:active, :admin] # login will be "admin-John Doe"
1173
+ factory :inactive_admin, traits: [:admin, :inactive] # login will be "Jane Doe (inactive)"
663
1174
  end
664
1175
  ```
665
1176
 
666
- You can also override individual attributes granted by a trait in subclasses.
1177
+ ### In child factories
1178
+
1179
+ You can override individual attributes granted by a trait in a child factory:
667
1180
 
668
1181
  ```ruby
669
1182
  factory :user do
670
1183
  name { "Friendly User" }
671
1184
  login { name }
672
1185
 
673
- trait :male do
1186
+ trait :active do
674
1187
  name { "John Doe" }
675
- gender { "Male" }
1188
+ status { :active }
676
1189
  login { "#{name} (M)" }
677
1190
  end
678
1191
 
679
1192
  factory :brandon do
680
- male
1193
+ active
681
1194
  name { "Brandon" }
682
1195
  end
683
1196
  end
684
1197
  ```
685
1198
 
686
- Traits can also be passed in as a list of symbols when you construct an instance from factory_bot.
1199
+ ### As mixins
1200
+
1201
+ Traits can be defined outside of factories and used as mixins to compose shared attributes
1202
+
1203
+ ```ruby
1204
+ FactoryBot.define do
1205
+ trait :timestamps do
1206
+ created_at { 8.days.ago }
1207
+ updated_at { 4.days.ago }
1208
+ end
1209
+
1210
+ factory :user, traits: [:timestamps] do
1211
+ username { "john_doe" }
1212
+ end
1213
+
1214
+ factory :post do
1215
+ timestamps
1216
+ title { "Traits rock" }
1217
+ end
1218
+ end
1219
+ ```
1220
+
1221
+ ### Using traits
1222
+
1223
+ Traits can also be passed in as a list of symbols when you construct an instance
1224
+ from factory\_bot.
687
1225
 
688
1226
  ```ruby
689
1227
  factory :user do
690
1228
  name { "Friendly User" }
691
1229
 
692
- trait :male do
1230
+ trait :active do
693
1231
  name { "John Doe" }
694
- gender { "Male" }
1232
+ status { :active }
695
1233
  end
696
1234
 
697
1235
  trait :admin do
@@ -699,8 +1237,8 @@ factory :user do
699
1237
  end
700
1238
  end
701
1239
 
702
- # creates an admin user with gender "Male" and name "Jon Snow"
703
- create(:user, :admin, :male, name: "Jon Snow")
1240
+ # creates an admin user with :active status and name "Jon Snow"
1241
+ create(:user, :admin, :active, name: "Jon Snow")
704
1242
  ```
705
1243
 
706
1244
  This ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.
@@ -718,10 +1256,12 @@ factory :user do
718
1256
  end
719
1257
  end
720
1258
 
721
- # creates 3 admin users with gender "Male" and name "Jon Snow"
722
- create_list(:user, 3, :admin, :male, name: "Jon Snow")
1259
+ # creates 3 admin users with :active status and name "Jon Snow"
1260
+ create_list(:user, 3, :admin, :active, name: "Jon Snow")
723
1261
  ```
724
1262
 
1263
+ ### With associations
1264
+
725
1265
  Traits can be used with associations easily too:
726
1266
 
727
1267
  ```ruby
@@ -762,6 +1302,8 @@ end
762
1302
  create(:post).author
763
1303
  ```
764
1304
 
1305
+ ### Traits within traits
1306
+
765
1307
  Traits can be used within other traits to mix in their attributes.
766
1308
 
767
1309
  ```ruby
@@ -777,6 +1319,8 @@ factory :order do
777
1319
  end
778
1320
  ```
779
1321
 
1322
+ ### With transient attributes
1323
+
780
1324
  Finally, traits can accept transient attributes.
781
1325
 
782
1326
  ```ruby
@@ -795,9 +1339,103 @@ end
795
1339
  create :invoice, :with_amount, amount: 2
796
1340
  ```
797
1341
 
1342
+ ### Enum traits
1343
+
1344
+ Given an Active Record model with an enum attribute:
1345
+
1346
+ ```rb
1347
+ class Task < ActiveRecord::Base
1348
+ enum status: {queued: 0, started: 1, finished: 2}
1349
+ end
1350
+
1351
+ ```
1352
+
1353
+ factory\_bot will automatically define traits for each possible value of the
1354
+ enum:
1355
+
1356
+ ```rb
1357
+ FactoryBot.define do
1358
+ factory :task
1359
+ end
1360
+
1361
+ FactoryBot.build(:task, :queued)
1362
+ FactoryBot.build(:task, :started)
1363
+ FactoryBot.build(:task, :finished)
1364
+ ```
1365
+
1366
+ Writing the traits out manually would be cumbersome, and is not necessary:
1367
+
1368
+ ```rb
1369
+ FactoryBot.define do
1370
+ factory :task do
1371
+ trait :queued do
1372
+ status { :queued }
1373
+ end
1374
+
1375
+ trait :started do
1376
+ status { :started }
1377
+ end
1378
+
1379
+ trait :finished do
1380
+ status { :finished }
1381
+ end
1382
+ end
1383
+ end
1384
+ ```
1385
+
1386
+ If automatically defining traits for enum attributes on every factory is not
1387
+ desired, it is possible to disable the feature by setting
1388
+ `FactoryBot.automatically_define_enum_traits = false`
1389
+
1390
+ In that case, it is still possible to explicitly define traits for an enum
1391
+ attribute in a particular factory:
1392
+
1393
+ ```rb
1394
+ FactoryBot.automatically_define_enum_traits = false
1395
+
1396
+ FactoryBot.define do
1397
+ factory :task do
1398
+ traits_for_enum(:status)
1399
+ end
1400
+ end
1401
+ ```
1402
+
1403
+ It is also possible to use this feature for other enumerable values, not
1404
+ specifically tied to Active Record enum attributes.
1405
+
1406
+ With an array:
1407
+
1408
+ ```rb
1409
+ class Task
1410
+ attr_accessor :status
1411
+ end
1412
+
1413
+ FactoryBot.define do
1414
+ factory :task do
1415
+ traits_for_enum(:status, ["queued", "started", "finished"])
1416
+ end
1417
+ end
1418
+ ```
1419
+
1420
+ Or with a hash:
1421
+
1422
+ ```rb
1423
+ class Task
1424
+ attr_accessor :status
1425
+ end
1426
+
1427
+ FactoryBot.define do
1428
+ factory :task do
1429
+ traits_for_enum(:status, { queued: 0, started: 1, finished: 2 })
1430
+ end
1431
+ end
1432
+ ```
1433
+
798
1434
  Callbacks
799
1435
  ---------
800
1436
 
1437
+ ### Default callbacks
1438
+
801
1439
  factory\_bot makes available four callbacks for injecting some code:
802
1440
 
803
1441
  * after(:build) - called after a factory is built (via `FactoryBot.build`, `FactoryBot.create`)
@@ -816,6 +1454,8 @@ end
816
1454
 
817
1455
  Note that you'll have an instance of the user in the block. This can be useful.
818
1456
 
1457
+ ### Multiple callbacks
1458
+
819
1459
  You can also define multiple types of callbacks on the same factory:
820
1460
 
821
1461
  ```ruby
@@ -825,7 +1465,8 @@ factory :user do
825
1465
  end
826
1466
  ```
827
1467
 
828
- Factories can also define any number of the same kind of callback. These callbacks will be executed in the order they are specified:
1468
+ Factories can also define any number of the same kind of callback. These
1469
+ callbacks will be executed in the order they are specified:
829
1470
 
830
1471
  ```ruby
831
1472
  factory :user do
@@ -836,9 +1477,12 @@ end
836
1477
 
837
1478
  Calling `create` will invoke both `after_build` and `after_create` callbacks.
838
1479
 
839
- Also, like standard attributes, child factories will inherit (and can also define) callbacks from their parent factory.
1480
+ Also, like standard attributes, child factories will inherit (and can also
1481
+ define) callbacks from their parent factory.
840
1482
 
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).
1483
+ Multiple callbacks can be assigned to run a block; this is useful when building
1484
+ various strategies that run the same code (since there are no callbacks that are
1485
+ shared across all strategies).
842
1486
 
843
1487
  ```ruby
844
1488
  factory :user do
@@ -848,6 +1492,8 @@ factory :user do
848
1492
  end
849
1493
  ```
850
1494
 
1495
+ ### Global callbacks
1496
+
851
1497
  To override callbacks for all factories, define them within the
852
1498
  `FactoryBot.define` block:
853
1499
 
@@ -862,7 +1508,9 @@ FactoryBot.define do
862
1508
  end
863
1509
  ```
864
1510
 
865
- You can also call callbacks that rely on `Symbol#to_proc`:
1511
+ ### Symbol#to_proc
1512
+
1513
+ You can call callbacks that rely on `Symbol#to_proc`:
866
1514
 
867
1515
  ```ruby
868
1516
  # app/models/user.rb
@@ -885,15 +1533,16 @@ create(:user) # creates the user and confirms it
885
1533
  Modifying factories
886
1534
  -------------------
887
1535
 
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.
1536
+ If you're given a set of factories (say, from a gem developer) but want to
1537
+ change them to fit into your application better, you can modify that factory
1538
+ instead of creating a child factory and adding attributes there.
890
1539
 
891
1540
  If a gem were to give you a User factory:
892
1541
 
893
1542
  ```ruby
894
1543
  FactoryBot.define do
895
1544
  factory :user do
896
- full_name "John Doe"
1545
+ full_name { "John Doe" }
897
1546
  sequence(:username) { |n| "user#{n}" }
898
1547
  password { "password" }
899
1548
  end
@@ -907,7 +1556,6 @@ FactoryBot.define do
907
1556
  factory :application_user, parent: :user do
908
1557
  full_name { "Jane Doe" }
909
1558
  date_of_birth { 21.years.ago }
910
- gender { "Female" }
911
1559
  health { 90 }
912
1560
  end
913
1561
  end
@@ -920,7 +1568,6 @@ FactoryBot.modify do
920
1568
  factory :user do
921
1569
  full_name { "Jane Doe" }
922
1570
  date_of_birth { 21.years.ago }
923
- gender { "Female" }
924
1571
  health { 90 }
925
1572
  end
926
1573
  end
@@ -950,6 +1597,23 @@ To set the attributes for each of the factories, you can pass in a hash as you n
950
1597
  twenty_year_olds = build_list(:user, 25, date_of_birth: 20.years.ago)
951
1598
  ```
952
1599
 
1600
+ In order to set different attributes for each factory, these methods may be passed a block, with the factory and the index as parameters:
1601
+
1602
+ ```ruby
1603
+ twenty_somethings = build_list(:user, 10) do |user, i|
1604
+ user.date_of_birth = (20 + i).years.ago
1605
+ end
1606
+ ```
1607
+
1608
+ `create_list` passes saved instances into the block. If you modify the instance, you must save it again:
1609
+
1610
+ ```ruby
1611
+ twenty_somethings = create_list(:user, 10) do |user, i|
1612
+ user.date_of_birth = (20 + i).years.ago
1613
+ user.save!
1614
+ end
1615
+ ```
1616
+
953
1617
  `build_stubbed_list` will give you fully stubbed out instances:
954
1618
 
955
1619
  ```ruby
@@ -972,7 +1636,7 @@ users_attrs = attributes_for_list(:user, 25) # array of attribute hashes
972
1636
  Linting Factories
973
1637
  -----------------
974
1638
 
975
- factory_bot allows for linting known factories:
1639
+ factory\_bot allows for linting known factories:
976
1640
 
977
1641
  ```ruby
978
1642
  FactoryBot.lint
@@ -999,8 +1663,10 @@ namespace :factory_bot do
999
1663
  desc "Verify that all FactoryBot factories are valid"
1000
1664
  task lint: :environment do
1001
1665
  if Rails.env.test?
1002
- DatabaseCleaner.cleaning do
1666
+ conn = ActiveRecord::Base.connection
1667
+ conn.transaction do
1003
1668
  FactoryBot.lint
1669
+ raise ActiveRecord::Rollback
1004
1670
  end
1005
1671
  else
1006
1672
  system("bundle exec rake factory_bot:lint RAILS_ENV='test'")
@@ -1012,8 +1678,7 @@ end
1012
1678
 
1013
1679
  After calling `FactoryBot.lint`, you'll likely want to clear out the
1014
1680
  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.
1681
+ uses an sql transaction and rollback to leave the database clean.
1017
1682
 
1018
1683
  You can lint factories selectively by passing only factories you want linted:
1019
1684
 
@@ -1047,10 +1712,17 @@ You can also specify the strategy used for linting:
1047
1712
  FactoryBot.lint strategy: :build
1048
1713
  ```
1049
1714
 
1715
+ Verbose linting will include full backtraces for each error, which can be
1716
+ helpful for debugging:
1717
+
1718
+ ```ruby
1719
+ FactoryBot.lint verbose: true
1720
+ ```
1721
+
1050
1722
  Custom Construction
1051
1723
  -------------------
1052
1724
 
1053
- If you want to use factory_bot to construct an object where some attributes
1725
+ If you want to use factory\_bot to construct an object where some attributes
1054
1726
  are passed to `initialize` or if you want to do something other than simply
1055
1727
  calling `new` on your build class, you can override the default behavior by
1056
1728
  defining `initialize_with` on your factory. Example:
@@ -1078,7 +1750,7 @@ end
1078
1750
  build(:user).name # Jane Doe
1079
1751
  ```
1080
1752
 
1081
- Although factory_bot is written to work with ActiveRecord out of the box, it
1753
+ Although factory\_bot is written to work with ActiveRecord out of the box, it
1082
1754
  can also work with any Ruby class. For maximum compatibility with ActiveRecord,
1083
1755
  the default initializer builds all instances by calling `new` on your build class
1084
1756
  without any arguments. It then calls attribute writer methods to assign all the
@@ -1089,7 +1761,7 @@ You can override the initializer in order to:
1089
1761
 
1090
1762
  * Build non-ActiveRecord objects that require arguments to `initialize`
1091
1763
  * Use a method other than `new` to instantiate the instance
1092
- * Do crazy things like decorate the instance after it's built
1764
+ * Do wild things like decorate the instance after it's built
1093
1765
 
1094
1766
  When using `initialize_with`, you don't have to declare the class itself when
1095
1767
  calling `new`; however, any other class methods you want to call will have to
@@ -1116,7 +1788,7 @@ factory :user do
1116
1788
 
1117
1789
  name "John Doe"
1118
1790
 
1119
- initialize_with { new(attributes) }
1791
+ initialize_with { new(**attributes) }
1120
1792
  end
1121
1793
  ```
1122
1794
 
@@ -1151,7 +1823,7 @@ build(:user)
1151
1823
  User.new('value')
1152
1824
  ```
1153
1825
 
1154
- This prevents duplicate assignment; in versions of factory_bot before 4.0, it
1826
+ This prevents duplicate assignment; in versions of factory\_bot before 4.0, it
1155
1827
  would run this:
1156
1828
 
1157
1829
  ```ruby
@@ -1337,12 +2009,12 @@ with associations, as below:
1337
2009
 
1338
2010
  ```ruby
1339
2011
  FactoryBot.define do
1340
- factory :united_states, class: Location do
2012
+ factory :united_states, class: "Location" do
1341
2013
  name { 'United States' }
1342
2014
  association :location_group, factory: :north_america
1343
2015
  end
1344
2016
 
1345
- factory :north_america, class: LocationGroup do
2017
+ factory :north_america, class: "LocationGroup" do
1346
2018
  name { 'North America' }
1347
2019
  end
1348
2020
  end