0

If a User has many posts, and a post belongs to user, it's simple to do:

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {

            // Creates a User for every Post
            return factory(App\User::class)->create()->id;
        }
    ];
});

How do I accomplish the opposite? Instead, creating say 5 posts when a user is created and associating that post to the newly created user?

~Edit I am using laravel 5.2, and I've declared my model relationships in my models, so I now have:

$user = factory(App\User::class)->create();
$posts = factory(App\Post::class, 3)->make();
$user->posts()->saveMany($posts);

// Great, now I have a User and 3 Posts associated with that user. 


// However, now, I want let's say, 5 votes per post.
// I can't call $posts->votes(), so I iterate

foreach ($posts as $post) { 
    $votes = factory(App\Votes::class, 5)->make();
    $post->votes()->saveMany($votes);
}

Then any other relation to votes, etc would just be nested in the foreach.

Jeff Puckett
  • 37,464
  • 17
  • 118
  • 167
cnorris
  • 548
  • 4
  • 12

2 Answers2

2

I would use Model Events for that. In your AppServiceProvider, add the events as below:

namespace App\Providers;

use App\User;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        User::created(function ($user) {
            $posts = factory(App\Post::class, 3)->make();
            $user->posts()->saveMany($posts);
        });

        Post::created(function ($post){
            $votes = factory(App\Vote::class, 3)->make();
            $post->votes()->saveMany($votes);
        });
    }

Now you do not have to worry about the automatic creation, also, this should not be part of the Controller logic anyways.

Mina Abadir
  • 2,951
  • 2
  • 15
  • 20
1
$factory->define(App\User::class, function ($faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->email
    ];
});

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph
    ];
});


$user = factory(User::class)->create();

$post = factory(User::class)->create();

$user->posts()->associate($post);

Create 5 fakers in $posts

$posts = factory(App\Post::class, 3)->make();
$user->posts()->saveMany($posts);
Jilson Thomas
  • 7,165
  • 27
  • 31
  • Currently I'm doing something similar to [this](http://stackoverflow.com/questions/32540845/adding-relations-to-laravel-factory-model) - but my problem is I have several relationships so it gets pretty messy. Is there any way I can accomplish this from the ModelFactory, or is there a good approach to nesting this stuff? Eg: A Group has # Users and Users have # Posts, and Posts have # comments, etc – cnorris Mar 19 '16 at 18:42
  • Instead of nesting everything in a single query, use the method I suggested. You can create different methods for each Model types and use the `SaveMany` or `save` methods to associate relationships with the user. Even the one you are referring to is pretty messy. – Jilson Thomas Mar 19 '16 at 18:45
  • So _associate_ doesn't seem to be a function, but I've put my understanding of what you were suggesting at the bottom of my question. Is that along the lines of what you were going for? Thanks! – cnorris Mar 19 '16 at 20:04
  • You can use `save` instead of that. – Jilson Thomas Mar 19 '16 at 20:05