112

The Factory Girl introduction delineates the difference between FactoryGirl.build() and FactoryGirl.create():

# Returns a User instance that's not saved
user = FactoryGirl.build(:user)

# Returns a saved User instance
user = FactoryGirl.create(:user)

I still don't understand the practical differences between the two. Can someone give an example where you would want to use one and not the other? Thanks!

Jonathan Scholbach
  • 4,925
  • 3
  • 23
  • 44
Son of the Wai-Pan
  • 12,371
  • 16
  • 46
  • 55

3 Answers3

148

The create() method persists the instance of the model while the build() method keeps it only on memory.

Personally, I use the create() method only when persistence is really necessary since writing to DB makes testing time consuming.

e.g.

I create users to authentication with create() because my authentication engine queries the DB.

To check if a model has an attribute the build() method will do because no DB access is required.

it{Factory.build(:user).should respond_to(:name)}

Update

"There is one exception that build actually 'creates' when you are building associations, i.e your association are no longer in memory but persisted. Keep that in mind" – Shakes

Stéphane Bruckert
  • 21,706
  • 14
  • 92
  • 130
Helio Santos
  • 6,606
  • 3
  • 25
  • 31
  • 21
    There is one exception that build actually 'creates' when you are building associations, i.e your association are no longer in memory but persisted. Keep that in mind – Shakes Jul 09 '14 at 09:50
  • @Shakes, I don't work in rails anymore. I'll check that as soon as I can. – Helio Santos Jul 09 '14 at 09:58
  • Has anyone made a tool to replace each instance of `create` with `build`, and undo it if the test fails? – mgold Jan 14 '16 at 18:33
  • Does `#create` read and return the persisted object from disk, or does it return the object that's in memory after persisting it? In other words, is is doing `create(...)` equivalent to `create(...).reload`? – Dennis Oct 06 '16 at 10:01
20

Using FactoryGirl.build(:factory_name) does not persist to the db and does not call save!, so your Active Record validations will not run. This is much faster, but validations might be important.

Using FactoryGirl.create(:factory_name) will persist to the db and will call Active Record validations. This is obviously slower but can catch validation errors (if you care about them in your tests).

totymedli
  • 29,531
  • 22
  • 131
  • 165
chasm
  • 361
  • 2
  • 8
  • 15
    Or, you could just do FactoryGirl.build(:factory_name).valid? which run validations without saving to database. – jinavar1 Jan 31 '14 at 14:09
5

FactoryGirl.create() will create new object and associations (if the factory has any) for it. They will all be persisted in a database. Also, it will trigger both model and database validations. Callbacks after(:build) and after(:create) will be called after the factory is saved. Also before(:create) will be called before the factory is saved.

FactoryGirl.build() won't save an object, but will still make requests to a database if the factory has associations. It will trigger validations only for associated objects. Callback after(:build) will be called after the factory is built.

Note that in most cases when testing models are best to use build_stubbed for better performance. Read more about it here.

hd1
  • 33,938
  • 5
  • 80
  • 91
Nesha Zoric
  • 6,218
  • 42
  • 34