matt.libera

matt.libera

Member Since 1 Year Ago

Greensboro, NC

Web Developer at UNCG

Experience Points 10,930
Experience Level 3

4,070 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 101
Lessons
Completed
Best Reply Awards 1
Best Reply
Awards
  • start-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-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-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist 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.

24 Jun
4 weeks ago

matt.libera left a reply on Can't Connect To Homestead (ping 192.168.10.10 Fails)

@HENDRA - This works beautifully. I was searching for a way to accomplish this without having to restart my host machine. I was able to verify vboxnet0 in the Virtualbox GUI, and made one tweak to your suggestion:

sudo ifconfig vboxnet0 down && sudo ifconfig vboxnet0 up worked for me - making sure the interface name is the same in both directives. (Otherwise it would fail on my machine.) For those looking for where to find this info, in Virtualbox GUI, go to Machine Tools > Details to ensure details are being shown, and then look in the Network pane - for me it was Adapter 2 (Host Only Adapter, 'vboxnet0')

Just wanted to give you some kudos for providing this workaround that doesn't require the entire host machine to be rebooted!

22 Mar
4 months ago

matt.libera left a reply on Get Fields From Table Related To Pivot Table

@SQUIRE - Happy to help! I'm glad you're enjoying Laravel. I started a couple years ago and haven't looked back! Such a great development experience.

matt.libera left a reply on Best Way To Have Multiple "child" Jobs Update A "parent" Job/model Status When All Have Completed?

@jlrdw Thanks for pointing me in the right direction. I've made that modification in my code and it feels like the right move. I'm putting aside the idea that the "child" jobs will report back to the "parent" and ascertaining the status of a Run by checking on its Actions, like I outlined above.

matt.libera left a reply on Call To Undefined Method Illuminate\Database\Query\Builder::save()

Yes, the key is that you're not using Eloquent.

If you were using Eloquent, @yassineqoraiche would be correct in that ->get() would return a set of results, whereas ->first() returns a single model, and ->save() would not work when using ->get() as it only works on a single Model.

If you can, I'd suggest using Eloquent; your code snippet looks very compatible. There can be reasons not to, but I don't readily see one from your code.

21 Mar
4 months ago

matt.libera left a reply on Get Fields From Table Related To Pivot Table

@SQUIRE - Well I had a whole explanation written up and then accidentally clicked a link to leave the page... and so there goes that 15 minutes...

The short story is that @itsricky is pointing you in the right direction.

Take it a step at a time. A Staff member can have many Roles, a Role can belong to many Staff members. That's a classic many-to-many relationship.

In Laravel, you'd handle it this way:

class Staff extends Model
{
    public function roles()
    {
        return $this->belongsToMany('App\Role');
    }
}

class Role extends Model
{
    public function staff()
    {
        return $this->belongsToMany('App\Staff');
    }
}

And you'd create a pivot table that contains both of these model names, singular, and alphabetically (so role_staff):

Schema::create('role_staff', function(Blueprint $table) {
    $table->increments('id');
    $table->unsignedInteger('role_id'); // or bigInteger or whatever you want to use
    $table->unsignedInteger('staff_id'); // same here
}

And that's it for the basic M2M relationship. We know from documentation that we can use $staff->roles()->attach($arrayOfRoleIdsHere) to attach Roles to a Staff member or detach() to remove, or my personal favorite sync() to pass in a complete list of what Roles the Staff member should have. That's all pretty basic stuff.

We also know that you can add custom fields to a pivot table:

Schema::create('role_staff', function(Blueprint $table) {
    $table->increments('id');
    $table->unsignedInteger('role_id'); // or bigInteger or whatever you want to use
    $table->unsignedInteger('staff_id'); // same here
    $table->unsignedInteger('assigned_by');
}

When using attach() or sync() you would make sure to explicitly pass values for any extra columns:

$staff->roles()->attach([
    1 => ['assigned_by' => 12] // we are saying that User 12 attached this Role to this Staff member
]);

Then, on your relationships you'd need to make sure you pull the extra columns from pivot:

class Staff extends Model
{
    public function roles()
    {
        return $this->belongsToMany('App\Role')->withPivot('assigned_by');
    }
}

class Role extends Model
{
    public function staff()
    {
        return $this->belongsToMany('App\Staff')->withPivot('assigned_by');
    }
}

When querying you can access any pivot columns with ->pivot:

$staff = Staff::with('roles')->first();
foreach ($staff->roles as $role) {
    echo $role->pivot->assigned_by; // outputs 12 in our example
}

That's great, but the problem comes in that Laravel doesn't know that 12 is actually a User ID. It's just a number. So we need to go a step farther, and explicitly define this relationship. But what IS this relationship? Well, this transaction must belong to a User, and a User may have many of these transactions. To do this, we do what @itsricky pointed you toward and create a model for your pivot table:

use Illuminate\Database\Eloquent\Relations\Pivot;

class RoleStaff extends Pivot
{
    public $incrementing = true; // need this for the `id` column on `role_staff` table

    public function user()
    {
        return $this->belongsTo('App\User', 'assigned_by'); // use 'assigned_by' here to tell the relationship what column to match off of.
    }
}

class User extends Model
{
    public function role_staff()
    {
        return $this->hasMany('App\RoleStaff', 'assigned_by') // same logic here.
    }
}

Then, finally, you can wrap this up by altering your Role and Staff models once more, so that they know to use this intermediate pivot model:

class Staff extends Model
{
    public function roles()
    {
        return $this->belongsToMany('App\Role')
                    ->using('App\RoleStaff')
                    ->withPivot('assigned_by');
    }
}

class Role extends Model
{
    public function staff()
    {
        return $this->belongsToMany('App\Staff')
                    ->using('App\RoleStaff')
                    ->withPivot('assigned_by');

    }
}

Now you can:

$staff = Staff::first();
foreach ($staff->roles as $role) {
    echo $role->pivot->user->username; // or whatever, off of your App\User class
    echo $role->name; // still works to get the name of the role
}

I think that should do it for you. Hopefully this accurately reflects your use case and I haven't missed anything. Have a read through the doc @itsricky linked to for more info on the intermediary table - but I would definitely recommend at least refactoring to follow the M2M conventions that Laravel has established.

Good luck!!

matt.libera left a reply on Get Fields From Table Related To Pivot Table

At first glance I'd say the relationship has not been set up quite right. It looks like you're kind of using a pivot table (meant for a many-to-many relationship). Let me ask:

  • How many Roles should a Staff member have?
  • If only one, then why the pivot table? Just to track the extra information (like what User added the Role to the Staff member)?

matt.libera left a reply on Best Way To Have Multiple "child" Jobs Update A "parent" Job/model Status When All Have Completed?

@JLRDW - Thanks :) I tend to get creative in my code / comments when I'm tired.

That older post does make sense (wonder why I couldn't find it in all my feverish searching)... at first I didn't really think it matched my situation 1:1 since I'm not asking the parent Job process to take any action itself or be cognizant of the other jobs it spawned.

But after thinking about it, I guess I'm basically doing the same thing by essentially persisting the "essence" of the Job to the database in Model form. The key concept raised by that article is that a Job should be self-sufficient and exist in its own "silo." With that in mind, I am leaning toward trying the idea I presented above... to see how badly it bogs down my database :)

Thanks for that.

Open to other suggestions too!

matt.libera started a new conversation Best Way To Have Multiple "child" Jobs Update A "parent" Job/model Status When All Have Completed?

OK. Hopefully this makes sense. I have the following:

  • A Job on the queue that reads a set of various data from the application and decides what actions need to be performed. For each of these actions, a new job is dispatched onto the queue.

  • I have a model representing the initial Job (we'll call it a "Run"). The Run has a status column on it, and a completed_at column as well. The status column is kept in addition because I want to know not only when it completed, but what its status was (completed, failed, error, etc.)

  • Each "child" job that was dispatched by the initial job is tied to the "Run" by ID (e.g. each job will receive the Run model in its constructor so it knows from whence it came).

What I am searching for is an easy way to update the "parent" Run status once the last child job has completed. I want to be able to easily grab the Run model and see that "oh yeah, it was successful" or "oh no, it had some errors."

I've tried a few different things, but the synchronous nature of the queue has provided some hiccups. I do not want to chain() the jobs because for me that defeats the purpose of having the queue. All of the child jobs are completely independent of the others (each makes an API call to an external service to perform a specific action), and so since none of the child jobs depend on the others completing, a chain just adds unnecessary wait time. I want to use the queue so that I can churn faster through the possibly hundreds of API calls I need the app to make.

What has worked the closest for me in the end is having each child job perform a check on the parent (Run) once it completes, to see if the Run has any outstanding actions (child jobs) that have not been completed yet. If it finds that the Run has no pending actions, it will update the row on the Run class with the appropriate status and completed_at values.

But I've found that this is still an imperfect solution; sometimes it works as expected; other times the status never gets set to "complete" even when all child jobs complete successfully. I'm guessing this is due to database locks and again the synchronous nature of the queue. I'm using Redis for the queue already, in case that helps.

So... anyone have any ideas how I might handle this? Or...do I take this step out completely, and rely on more database operations (have a model for each Action, with status), and perform more complex queries to ascertain the status of a Job based on its related Action entries in the database? My concern here is that the queries would add more overhead on the database side... but I would imagine I could do something like:

<?php

class Run
{
    //... boilerplate yada yada

    public function getStatusAttribute()
{
        $pendingActions = $this->actions->where('status', null)->get();
        return $pendingActions->isEmpty() ? 'completed' : 'pending';
    }
}

Obviously simplified here, but that's the thought. Would that be the way to go? Or is that too expensive on the database? Other ideas / experience?

Thanks.

25 Jul
11 months ago

matt.libera left a reply on Adding Content To A Blade Section More Than Once

Holy crap. A gem indeed, even today (years after the original post). Many thanks!

04 May
1 year ago

matt.libera started a new conversation Tests Fail With 404 When Laravel Installed In A Subfolder

OK, first - I understand that it is not recommended for Laravel to be installed in a subfolder (e.g. http://myapp.com/laravel). But... for our own reasons we need to be able to do it.

We've done this essentially by creating another folder in /var/www, and symlinking from /var/www/html/appname to /var/www/apps/myapp/public. This approach has been working very well for us, for the most part.

The only hiccup is around using absolute paths - we cannot use absolute paths in CSS or I believe url() directives in Laravel).

However, there is now an additional thing I stumbled on yesterday around testing with PHPUnit. Basically, all tests (even a basic $this->get('/') will fail with a 404 error:

Expected status code 200 but received 404.

I've messed around with changing APP_URL in the .env file, and also tried many suggestions online around changing the TestCase.php file to include the protected $baseUrl property, and nothing seemed to fix this except for moving my installation of Laravel to a TLD.

Does anyone have any suggestions for how I might be able to use PHPUnit on a Laravel app installed in a subfolder? Is this related to our other absolute-path woes?

TIA.