User Roles Many to Many

In a previous post, I shared how to create user roles with one to many relationship. Another way to design user roles in your application is to create a many to many relationship. This means many users can have many roles.

It is very similar as the previous design except you won’t have foreign keys in the users or roles table. There will be a pivot table that will have a foreign key for the users and roles table. You also won’t need to have the roles table created prior to the users table. But both users and roles table need to exist before the pivot table is created.

Let’s create the migration file for the roles table.

php artisan make:migration create_roles_table

Edit this file with the following code.

public function up()
{
    Schema::create('roles', function(Blueprint $table)
    {
        $table->id();
        $table->string('name', 50)->unique();
    });
}

Again, I chose not to have the timestamps columns, but you can if you wish. If you don’t want the timestamps column, you should add some code in your Role model class to let eloquent know. Your tables should look something like below.

Remember, we don’t have foreign keys on either table. We will now create a pivot table. Following naming conventions, it will be called role_user.

php artisan make:migration create_role_user_table

The up() in your migration file will contain the following code that defines the foreign keys for users and roles.

public function up()
{
    Schema::create('role_user', function (Blueprint $table) {
        $table->id();
        $table->foreignId('role_id')
            ->constrained('roles');
        $table->foreignId('user_id')
            ->constrained('users');
        $table->timestamps();
    });
}

Your role_user table looks like the following.

As a reminder, by default, Laravel creates INT columns as BIGINT when using id() and foreignId(). You can continue to use INT but you will have to use increments() for the primary key and the “long form” to define foreign keys that uses unsignedInteger() followed by foreign().

Next, create a model class for the role_user table.

php artisan make:model RoleUser

Edit this model class and add the following.

// app/Models/RoleUser.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class RoleUser extends Model
{
    use HasFactory;

    protected $table = 'role_user';
}

Defining $table is not necessary if you follow naming conventions but I tend to add it anyway.

Now we will add the many to many relationship between users and roles. To do this, add the following methods to the users and roles model classes.

// app/Models/Role.php

public function users()
{
    return $this->belongsToMany(User::class, 'role_user', 'role_id', 'user_id');
}

// app/Models/User.php

public function roles()
{
    return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');
}

You can read more about many to many relationships at https://laravel.com/docs/master/eloquent-relationships#many-to-many. Your tables should look something like this.

With this design, users can have more than one role. For example, user1 can have an admin role and staff. User2 can be admin, staff, and manager. And so on.

Vagrant and Laravel Timed Out While Waiting for the Machine to Boot

I have been able to develop Laravel applications on my Windows 10 environment for quite some time using Homestead. Recently, I have been getting errors when loading up the dev environment. The following error is happening.

Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured (“config.vm.boot_timeout” value) time period.

If you look above, you should be able to see the error(s) that
Vagrant had when attempting to connect to the machine. These errors
are usually good hints as to what may be wrong.

If you’re using a custom box, make sure that networking is properly
working and you’re able to connect to the machine. It is a common
problem that networking isn’t setup properly in these boxes.
Verify that authentication configurations are also setup properly,
as well.

If the box appears to be booting properly, you may want to increase
the timeout (“config.vm.boot_timeout”) value.

Sometimes the project would load on the browser, sometimes it won’t. Sometimes I can SSH into the VM sometimes, it would time out with this error.

ssh_exchange_identification: read: Connection reset

I use the same environment settings on Linux and macOS and have no issues running the environment. I’m guessing it could be permissions as Windows is different than *nix OS.

A solution I found was to enable GUI mode so that you can see what the VM is doing. If it’s getting stuck somewhere or if the system is waiting for a prompt to be answered. Here is a link that describes how to enable it https://stackoverflow.com/a/23742373/3893181. In my case, my config file did not have it commented out. I had to add it inside the Vagrant.configure block, at the bottom.

This window will open. So if there are any errors during boot, hopefully it will show here.

Now I’m able to see a message that may be causing my issue.

Spectre mitigation: LFENCE not serializing to generic retpoline?

Restarting vagrant/homestead seems to work… sometimes. But what could be causing it is having Docker Desktop installed alongside Virtualbox. I feel that’s when the errors started.

Luckily, Laravel has a new tool in version 8 called Laravel Sail. This uses Windows 10 WSL2 and Docker Desktop. I have uninstalled vagrant and virtualbox and have been using Laravel Sail. It has been working flawlessly on Windows. Finally, I can now have a stable dev environment in Windows. Even NPM commands work.

User Roles One to Many

There are many ways to handle user roles in an application. One way is to create a role(s) that have many user(s) or a one to many relationship. In this scenario, we can create a role called admin and many users can have this role. We can create another role called staff and this role can belong to more than one user. Now a user cannot have more than one role so the inverse relatationship is many to one.

By default, Laravel comes with a migration file to create a users table. Running the migration file, you will get a table with the following structure.

In more recent Laravel versions, the primary key is now a BIGINT datatype. If you open the migration file, it uses $table->id();. Previously, it uses $table->increments(‘id’); and that creates a primary key that uses INT datatype. You can still use either one as of Laravel v8. Just make sure when creating foreign keys, both columns matches up. I have been using the id() to simplify creating migration files. I’m not too concerned with data size.

Next, we need to create a migration file for the roles table.

php artisan make:migration create_roles_table

This will create a migration file. The file name is prefixed with the current timestamp. The roles table has to be created prior to the users table. Migration files are run in alphabetical order. You can either rename the roles migration file to have a timestamp before the user migration file or create another migration to add the foreign after both users and roles table are created. For me, the quickest is to rename the roles migration file so that it appears “above” the user migration file when alphabetized.

Edit the roles migration class with the following code.

public function up()
{
    Schema::create('roles', function(Blueprint $table)
    {
        $table->id();
        $table->string('name', 50)->unique();
    });
}

I chose not to keep the timestamp columns but you can keep them if you want. The migration file will create the following table.

Next, edit the users migration file and add the role_id foreign key. Add the code below within the up(). I normally place my foreign keys under the primary key.

// CreateUsersTable class
public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->foreignId('agency_id')->constrained('agencies');
        $table->string('name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
}

This will create the foreign key constraint between the users and roles table.

It is a good idea to create the relationships in your model classes as well. Create a model class for your roles table.

php artisan make:model Role

Edit the Role.php model class file.

// app/Models/Role.php

class Role extends Model
{
    use HasFactory;

    protected $table = 'roles';              // defines table name
    public $timestamps = false;         // no created_at or updated_at columns

    /**
     * Has many users.
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function users()
    {
        return $this->hasMany(User::class);
    }
}

You will need to define the relationship in your User model class.

// app/Models/User.php

/**
 * Relationship to role.
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function role()
{
        return $this->belongsTo(Role::class);
}

That’s all you need to do in terms of create users and roles relationship. The next step is to create a way to authorize users based on roles. You can either use Laravel’s Gates and Policies. Or you can create your own middleware.

3D Printing Is Not For Me

I have been curious about 3D printers for some time but the cost did not justify to quench my curiousity. Recently, the Creality Ender 3 Pro went on sale for $199.99 at Micro Center. I decided to pick one up and some PLA filament. The first print I tried is the dog demo that came with the printer.

At first, things were looking good. The first couple of layers look rough but I thought it was fine and it’ll straighten out. This print is supposed to take about 5 hours. More than halfway through it fell apart.

I should have leveled the bed

As you can see the first few layers were all over the place. The bed should have been leveld. The print failed because the level was off. Not sure why it took that long.

I downloaded a file to help level the bed and started to print the dog again. Another failed attempt.

The filament spool got tangled

This time the filament spool got tangled up. This was the starter spool. Instead of running into the issue again, I opened a new spool – one of the 1 kg spools I bought.

Okay, attempt number 3 on the dog. This time the nozzle got clogged after 2 hours of printing.

I am striking out with all these attempts. I took it apart, which was a good exercise. It helped me get more familiar with the printer. Cleaning wasn’t too difficult, just time consuming. I cleaned out the filament and put the printer back together. Here we go, attempt 4.

Success!

I finally got a successful print. It took several tries and many hours of waiting. Long filaments but the cost isn’t that bad. It’s mainly the time and power consumption. Even with this print, there is a stain on the right leg – may have been due to excessive heat/burn during the print. I was pretty excited to finally get one print done so I printed another and it completed without any issues.

The one I tried is the pig demo. It came out fine. This was a long print – around 6 hours. I am getting the hang of it and tried to print a knob for the printer. It failed a few times but finally printed correctly. Next was the cat demo. This failed. After that failure, I decided that 3D printing is not for me.

Just some of the failed attempts
Successful attempts

After some thing, I decided to return the printer before the return period expires. I just can’t get the hang of it. You invest a lot of time and electricity and from my experience, it gave me a low success rate. I also found many 3D printed items being sold on Etsy.

Noctua Is Too Big

I have been having bad luck with closed loop water coolers so I decided to try an air cooler. I also picked up new case, the Lian Li 011 Dynamic. Noctua fans are great so I went ahead and got the Noctua NH-D15 Chromax Black.

Noctua NH-D15 Chromax Black

Installation is fairly simple and the packaging is outstanding. Reminds me of opening up an Apple device. I was very excited to get this up and running and see improvements of noise and possibly lower temps. Unfotunately, my excitement was met with disappointment. It’s too tall. I cannot close the side panel.

The cooler is too tall

I should’ve read the reviews/comments. This cooler does not fit the Lian Li case. I didn’t want to get another case just to use the cooler. I opted to keep the Lian Li case and returned the Noctua cooler. If it weren’t for the spikes, I believe this cooler would fit. I couldn’t remove them.

I’m really contemplating on using this Noctua cooler on my next build and use a bigger case. Maybe look into another Fractal Design Define series or Corsair Obsidian series.

Apple Trade In With Phobio

I currently have a 2016 MacBook Pro. It’s been great but my biggest complaint is the keyboard. Fortunately, it doesn’t malfunction. It works as intended but that’s the problem. The butterfly keys are terrible and for a laptop, the keyboard and monitor are pretty much everything. I can plug in an USB keyboard but it won’t make it portable.

I paid $2799 for my 2016 MBP and the trade in value is only $710. I decided to bite the bullet and take a loss and trade in for the 2019 16″ MacBook Pro. Three things I’m after: the bigger screen (vs 15″), 8 cores (vs 4 cores), and “magic” keyboard AKA the old keyboard that shouldn’t have changed to begin with (vs butterfly keyboard). I bought the 2019 MBP online and started the process for the trade in. Phobio is the company that Apple uses for trade in. The plan is to pay for the 2019 laptop and once the trade in is completed, get the refund for $710 back on the card.

IMG_0398.JPG
2016 MBP (top), 2019 MBP (bottom)

Phobio sent out a box with shipping labels for me to pack up my old laptop and send it off for inspection and trade in. I took several pictures during the factory reset and noted the condition of the laptop. I am very careful with my stuff. These devices are expensive!

A few weeks later, I get an email from Phobio informing me that my trade value has been reduced from $710 to $250. They said they detected some screen damages during their inspection. Here is the photo they took and sent to me.

trade_asset-20484507130-5796d829f4cc4322999b30fd79cc00a1
Phobio found screen defects… can you see it?

I don’t see it and I also took photos before shipping my old laptop to them.

This slideshow requires JavaScript.

Do you see any imperfections on the screen? I don’t either. I declined the new trade in offer. I called Apple and Phobio for additional options. Phobio is firm with their decision. They say that the damage they saw could not have happened during transit but more of wear and tear damage. I told them that there is no damage when I sent it to them, could the damage occur while they were inspecting and testing – of course not.

They shipped the laptop back free of charge. After receiving it back, I inspected the laptop and did not find any screen damage as they described and photographed (I still don’t see it on the photo). I contacted Apple and they suggested to bring it into the store to do the trade in – but with COVID19, the stores are closed. I was nearing the return/refund deadline – which was extended from 14 days to 30 days due to the current situation. I didn’t want to risk not being able to get the trade in amount and/or get a refund on the new laptop so I just returned it and got a refund.

Working from home, I don’t need to be portable with the laptop so I just docked it with a keyboard and monitor – problem solved until the new ARM Macs come out and I’ll revisit the trade in option.

After this experience, I would definitely suggest to do your trade in inside the Apple store. Any screen damage will tremendously reduce the value. But at least when doing it in the store, you will know right away of the value. And they may be more lenient with imperfections.

Fix Your Favorite Headphones

I have a pair of Bose SoundTrue headphones I got back in 2015 and it has seen better days. I don’t want to throw them away since they work. The only problem it has is the worn earpads.

DSC00240.jpg
Bose SoundTrue

I called Bose to see if they could help me. They have cushion kits for sale but at the cost of $34. They have the black ones (329586-0010) or white ones (626655-0040). I got these headphones during Black Friday for $60. Getting those replacement pads for that price is not a good idea.

I searched on Amazon and found them cheaper for $29.95 but it’s still too expensive. I might as well get new headphones. I found an alternative for a lower cost from Amazon.

DSC00242
Earpad Replacement

They are easy to replace. The pads are held with clips. You just remove and replace.

DSC00244.jpg
Clips hold the pads in place

The fit is good. You just have to go around and make sure the edges are under the clips.

DSC00246
Nice fit, good as new

I decided not to use the L and R dust-proof scrim. I kept the blue ones in. It’s easy to determine which is left and which is right. Just put them on and you’ll feel it. Otherwise, the cable is always on the left side ear. Now to find a headband replacement. The support is still there but the fabric is getting worn as well.

My other headphones, Audio Technica M50 headband is worn. Again, I called the company and was told to send them the headphones and pay a fee for them to replace it.

DSC00248.jpg
Audio Technica M50

I found a zipped up cover and it solved my problem.

DSC00250
Zipped up cover

Make sure the zipper is on top or it will head our head when you’re using it. It fits snug.

DSC00253.jpg
What a mess

As I was fitting the cover, all the headband material started coming off. This is why I wanted a cover. Now I can continue to use and enjoy my old headphones.

The best USB C dongle for your 2019 MacBook Pro

I recently traded my 2016 MacBook Pro for a 2019 MVVK2LL/A model (8 cores) for obvious reasons (“magic” keyboard and more cores). With this generation of MBPs, you will need a dongle sooner or later. I have been using this dongle for a few years.

doedoeflu_dongle
doedoeflu dongle

It has mostly every thing I need. USB3 A ports, C ports, card reader and most importantly HDMI. I tend to dock my MBP when I’m at home because the keyboard is just unusuable and I like using a larger monitor. The only port I wish it had was an ethernet port.

Wifi is convenient but I don’t really like using it with computers. I transfer data between my home server and other computers on the network. Wifi is slow compared to being plugged in. So I end up using a USB-C to A adapter and a USB3 Gigabit LAN adapter. Yes, another dongle.

usbc_to_usba_gigabit_ethernet_dongle.jpg
Tendak SuperSpeed USB 3.0 to RJ45

The current dongle works with the 16″ MBP. The connectors are the same – dual USB-C. I figured, new laptop, new dongle but this time get one with an ethernet port. There are more dongles available now and at competitive pricing. I was able to find one from Saferell that checks all the boxes.

saferell_dongle.jpg
Saferell dongle

The dongle consist of 2x USB3 Type-C ports just like the previous dongle. It takes up one side of the laptop. With all those ports, it utilizes both ports. It has a way to run the power adapter as well. It has everything I need from the previous dongle and more. It has gigabit ethernet and 2 HDMI ports.

DSC00229
2 HDMI ports

Now the description may say triple display but it only has 2 HDMI ports. The third display is the laptop itself so don’t misunderstand thinking there are 3 HDMI ports or 2 HDMI plus an addition display port.

I’ve been using it for a few hours with one HDMI external display. I have a HP 27″ 1440p monitor. I don’t have any 4K displays but it does run at 60Hz. I don’t game on my laptop, mainly coding so the refresh rate is fine. It does run warm so be aware of that.

DSC00225.jpg
Card readers

I’m still disappointed that Apple removed the card reader but at least most dongles have card readers. This one has a reader for SD and Micro SD cards.

The USB-C can accept the 100W charger and will charge through the dongle. Or you can charge on the other side of the laptop where the other 2 USB-C ports are open.

The dongle plug is on a stiff cable and I prefer this design than the previous dongle. It makes the dongle more flexible where I can position in different positions.

DSC00231
Flexible plug

It makes it a larger dongle but it’s fine. I mainly use the dongle when I’m at home “docked”. I rarely use the dongle when I’m out or moving around the house.

I’ve always preferred the Space Gray over Silver – on my laptops, watch, and iPhone. If they had matte black, I’d be all over it. Between the two dongles, I feel the Saferell matches better.

DSC00230.jpg
Space gray

I’m really pleased with it so far. Do you use a dongle? Which one do you use. What port do you miss the most?