codinglukas

Member Since 5 Months Ago

Experience Points
2,550
Total
Experience

2,450 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
25
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

  • Community Pillar

    Earned once your experience points ranks in the top 10 of all Laracasts users.

Level 1
2,550 XP
May
08
1 month ago
Activity icon

Started a new Conversation How To Pass Ids Between Factories With Nested Relations For Laravel 8?

Hello All,

I want to create a factory with multi-level relations while everything would connect with ids without the use of the database (->make()), but if needed it would work with the database either (->create()).

I have achieved it, but it looks hacky. Does anybody know a better way to achieve the same result?

Code:

Laptop.php

class Laptop extends Model
{
    use HasFactory;

    public function keyboard(): HasOne
    {
        return $this->hasOne(Keyboard::class);
    }
}

Keyboard.php

class Keyboard extends Model
{
    use HasFactory;

    public function keyboardButtons(): HasMany
    {
        return $this->hasMany(KeyboardButton::class);
    }

    public function laptop(): BelongsTo
    {
        $this->belongsTo(Laptop::class);
    }
}

KeyboardButton.php

class KeyboardButton extends Model
{
    use HasFactory;

    public function keyboard(): BelongsTo
    {
        return $this->belongsTo(Keyboard::class);
    }
}

LaptopFactory.php

class LaptopFactory extends Factory
{
    protected $model = Laptop::class;
    
    public function definition()
    {
        return [
            //
        ];
    }
    
    public function configure()
    {
        return $this->afterMaking(function (Laptop $laptop) {
            $data = [];

            if($laptop->id !== null){
                $data['laptop_id'] = $laptop->id;
            }

            if($laptop->keyboard_id !== null){
                $data['id'] = $laptop->keyboard_id;
                $laptop->offsetUnset('keyboard_id');
            }

            $laptop->setRelation('keyboard', Keyboard::factory()->make($data));
        })->afterCreating(function (Laptop $laptop) {
            $data = [];

            if($laptop->id !== null){
                $data['laptop_id'] = $laptop->id;
            }

            $laptop->setRelation('keyboard', Keyboard::factory()->create($data));

            $laptop->push();
        });
    }
}

KeyboardFactory.php

class KeyboardFactory extends Factory
{
    protected $model = Keyboard::class;
    
    public function definition()
    {
        return [
            //
        ];
    }
    
    public function configure()
    {
        return $this->afterMaking(function (Keyboard $keyboard) {
            $data = [];

            if($keyboard->id !== null){
                $data['keyboard_id'] = $keyboard->id;
            }

            $keyboard->setRelation('keyboardButtons', KeyboardButton::factory()->count(10)->make($data));
        })->afterCreating(function (Keyboard $keyboard) {
            $data = [];

            if($keyboard->id !== null){
                $data['keyboard_id'] = $keyboard->id;
            }

            $keyboard->setRelation('keyboardButtons', KeyboardButton::factory()->count(10)->create($data));
        });
    }
}

KeyboardButtonFactory.php

class KeyboardButtonFactory extends Factory
{
    protected $model = KeyboardButton::class;
    
    public function definition()
    {
        return [
            //
        ];
    }
}

Results:

On make (no database!) As you can see Laptop passes it's id to the relation Keyboard (laptop_id = 2) and then Keyboard passes it's id of 10 to the KeyboardButton (keyboard_id = 10).

 App\Models\Laptop::factory()->make(['id' => 2, 'keyboard_id' => 10]);
=> App\Models\Laptop {#4410
     id: 2,
     keyboard: App\Models\Keyboard {#4411
       laptop_id: 2,
       id: 10,
       keyboardButtons: Illuminate\Database\Eloquent\Collection {#3463
         all: [
           App\Models\KeyboardButton {#3455
             keyboard_id: 10,
           },
           App\Models\KeyboardButton {#4369
             keyboard_id: 10,
           },
...

In scenario with database, ids connect either!

App\Models\Laptop::factory()->create();
=> App\Models\Laptop {#4418
     updated_at: "2021-05-08 14:26:48",
     created_at: "2021-05-08 14:26:48",
     id: 25,
     keyboard: App\Models\Keyboard {#3398
       laptop_id: 25,
       updated_at: "2021-05-08 14:26:48",
       created_at: "2021-05-08 14:26:48",
       id: 10,
       keyboardButtons: Illuminate\Database\Eloquent\Collection {#4406
         all: [
           App\Models\KeyboardButton {#4402
             keyboard_id: 10,
             updated_at: "2021-05-08 14:26:48",
             created_at: "2021-05-08 14:26:48",
             id: 37,
           },
           App\Models\KeyboardButton {#4405
             keyboard_id: 10,
             updated_at: "2021-05-08 14:26:48",
             created_at: "2021-05-08 14:26:48",
             id: 38,
           },
...

But Factocies code looks hacky and hardly maintainable within a larger application.

What would be better way to achieve same results as I outputted before?