Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

anshbargoti's avatar

Create vs Make method

I have three tables; users, categories, posts and have a relationship between them as

  1. A user can have many posts
  2. A post belongs to user and can have many categories
  3. A category can have many posts

PostFactory.php

public function definition()
    {
        return [
            'user_id' => User::factory(),
            'category_id' => Category::factory(),
            'title' => $this->faker->sentence,
            'slug' => $this->faker->slug,
            'excerpt' => $this->faker->sentence,
            'body' => $this->faker->paragraph
        ];
    }

UserFactory.php

public function definition()
    {
        return [
            'username' => $this->faker->unique()->userName,
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => 'yIXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }

CategoryFactory.php

public function definition()
    {
        return [
            'name' => $this->faker->word,
            'slug' => $this->faker->slug
        ];
    }

So, Whenever I am creating a fake data for post, using Tinker as Post::factory()->create() then it basically create and persist new user, new category and new post to the database but when I am using Post::factory()->make() then it should return the instance of post and make the instance of user and category return it to user_id and category_id but not persist the User and Category entry to database until I call save or create method on post. But it's creating and saving the new User and new Category to the database and returning a instance to Post. So why does it persist User and Category to database.

** AND **

Also, If I use the create method for category inside postfactory as 'category_id' => Category::factory()->create(), then it should save the category to database and return an instance when I will be using Post::factory()->create inside tinker but why it's not good practice to do that('category_id' => Category::factory()->create()) or what's the difference apart from this one "saving to database and returning an instance when using create method, and If I don't then it will first return an instance but will save later"

PostFactory.php

public function definition()
    {
        return [
            'user_id' => User::factory(),
            'category_id' => Category::factory()->create(),
            'title' => $this->faker->sentence,
            'slug' => $this->faker->slug,
            'excerpt' => $this->faker->sentence,
            'body' => $this->faker->paragraph
        ];
    }
0 likes
5 replies
cwhite's avatar

You should use factories inside your factory definitions instead of creating models:

public function definition()
    {
        return [
            'user_id' => User::factory(),
            'category_id' => Category::factory(),
            'title' => $this->faker->sentence,
            'slug' => $this->faker->slug,
            'excerpt' => $this->faker->sentence,
            'body' => $this->faker->paragraph
        ];
    }

If you don't, then a Category will be created when the array is returned even if you later override that category.

E.g., Post::factory()->create(['category_id' => $category->id'); will create a Category model that's not used

1 like
anshbargoti's avatar

@cwhite Thanks, so Basically it means that If I use 'create' method for 'category_id' then I won't be able to override the things and it will every time create new instance and save it to database and then return the created model instance to 'category_id'

anshbargoti's avatar

@cwhite Also, Could you just look over the first question, If I call make method for post as Post::factory()->make() then the user and category fake entries are getting saved into database and Post instance is getting returned so it should just create instance for user and category and not save into database or Is this the correct explanation for this situation =>

Post::factory()->make() with category_id set to Category::factory() will save the new Category instance to the database even though we're only creating a new Post instance and not actually saving it.

The reason this happens is because make() and create() methods are separate operations. make() creates a new model instance, but it doesn't actually save it to the database. However, when we use Category::factory() inside the make() method for Post, we are effectively calling Category::factory()->create(), which saves the new Category instance to the database.

cwhite's avatar

@anshbargoti

The reason this happens is because make() and create() methods are separate operations. make() creates a new model instance, but it doesn't actually save it to the database. However, when we use Category::factory() inside the make() method for Post, we are effectively calling Category::factory()->create(), which saves the new Category instance to the database

Not necessarily, it just depends on when the model needs an id from the factory (i.e., it needs to be saved to the database). A factory will create another factory when it's needed.

In this particular instance, calling Post::factory()->make() should create a Category because it needs the ID to populate the post model with before it can be saved (in the create hook)

1 like

Please or to participate in this conversation.