Using the Logged in User's ID within your Application

Now that we have the ability to login there are things that we can do with the user's login information to improve the user experience and ease of use of the application in relation to certain use cases within the application. Once the user has logged in, it should no longer be necessary for the user to supply any information which may be required as part of certain actions. Previously, when booking a tennis court, it was necessary for the user to pick their userid from a drop down list of users. This is a clearly flawed approach. It is easy for anyone to book a court in another persons name. The system is open to being abused. It would make much more sense if only logged in users who were registered members of the club could book a court. If the user was logged in, it should not be necessary for the user to supply their memberid as it should be possible to pick up this information from the user login.

In order to achieve this, we need to introduce a relationship between the Member and User tables/classes. There are a number of approaches to introducing this relationship. In purely correct terms it is likely that a Member "is a type of" User. This introduces what, in relational databases is terminology is referred to as a Specialization-Generalization relationship, and in Object Oriented Programming is referred to as Inheritance. A UML model to represent this might look something like this:

Having introduced the User table in the way we did also introduces a problem in relation to normalization and functional dependency within our database. We now have the member's name stored both in the User and in the Member table. This breaks cardinal rules in relation to duplication of data in relational databases.

Despite these issues, we really need some way to pick up the member's id from the logged in session information. One thing we could do would be to change our database around so that it's the User that makes a booking and has a relationship with the booking table. This could be made to work but there may be an easier way.

A more straightforward approach will be to introduce a one to one relationship between the member and the user table by adding a userid foreign key field to the member table. It's not a perfect model for the way this relationship truly "is" but it can be made to work well in this situation.

Modify the member table in the database using the following sql script.

alter table member add column userid bigint unsigned;
alter table member add constraint FK_member_user foreign key(userid) references users(id);
ALTER TABLE member add constraint FK_member_user_unique UNIQUE (userid);

This effectively creates a one-to-one relationship between the users and member table. Next we need to modify the respective model classes to reflect this one-to-one relationship.

Modify the \app\models\member.php class to add the following function at the bottom of the class.

public function user()
{
    return $this->belongsTo(\App\User::class,'userid','id');
}

Next modify the app\User.php class to add a hasOne relationship as follows

public function member()
{
    return $this->hasOne(\App\Models\Member::class, 'userid');
}

Now that we have specified the relationship in our model classes the beauty of Object Relationship Mapping kicks in. Before we can use the Auth class we need to make sure it's added to the top of the memberController.php file with the other use clauses as follows:

use Illuminate\Support\Facades\Auth;

Now, if ever we need to retrieve attributes from the Member.php model, we can simply "walk" the object relationship that exists between them as follows:

Before we can do this we need to give one of our members a userid. Use the route http://localhost:8000/register to register a new user of the system. Use the name Morgan Bartlett. After registering the User, query your database to check the id that was assigned to your new user

Use this new id to create a relationship between this user and the Tennis Club member Morgan Bartlett.

update member set userid=3 where firstname="Morgan" and surname="Bartlett";

Make sure you set the user id to whatever the id of your new user was.

To see all this in action, add the following function to app\Http\controllers\memberController.php

public function getLoggedInMemberDetails()
{

    if (!Auth::guest()){
        $user = Auth::user();
        echo "Userid is " . $user->id;    
        echo "Member id is " . $user->member->id;
        echo "The member's name is " . $user->member->firstname . " ";
        echo $user->member->surname;
        echo "The member is a " . $user->member->membertype;
    }
    else {
        echo "not logged in ";
    }
}

And add the following route to routes\web.php so that you can access the new function

Route::get('/loggedInMember','App\Http\Controllers\memberController@getLoggedInMemberDetails');

Now, once you've logged in as Morgan Bartlett, using the credentials you gave when you registered, if you visit http://localhost:8000/loggedInMember you should see the following information

In the next step we'll use this information to create a new booking for that member without having to pull the member's id from a dropdown list.

Leave a Reply