Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

rokkan's avatar

How do I check what type the Model is?

How can I check if a model is a User model or some kind of other model? Like is there a way to check the model type?

Like verify the model is for example a User model or Task model?

0 likes
31 replies
rokkan's avatar

@Ruffles I have a User table and an Admin table for 2 different model types. When someone is authenticated I want to check which model type they are. I know I can create a column field for each model that says their type but I'm wondering if I can skip that and just check what model type they are?

I just want to know how to do it. I know I can merge the 2 tables together but I don't want to for several reasons.

rokkan's avatar

@pmall

Created a Middleware: but it never seems to return true? Always redirects to home

namespace App\Http\Middleware;

use Closure;
use App\Admin;

class AdminMiddleware
{

    public function handle($request, Closure $next)
    {
        if ($request->user() instanceof Admin) 
        { 
            return $next($request);
        } else {
            return redirect('home');
        }

        return $next($request);
     }
}
1 like
pmall's avatar

I think you have to put the full class name \App\Admin

rokkan's avatar

@pmall Thanks, Well I found out the issue I'm running into now is my Admin login is checking against the User table not letting me login as Admin. I checked the Db and the Admin register successfully makes an entry into the Admin table. How do I make the Admin login check against the Admin table and not the User table?

pmall's avatar

You cant have two different tables for Auth

rokkan's avatar

@pmall I cant tell Auth to instead check Admin table instead of users through the controller?

pmall's avatar

No there is no way. Thats why everyone makes roles.

pmall's avatar

You should create roles. It is as simple as putting a is_admin column in the users table.

rokkan's avatar

@pmall but what about the extra columns an admin will have that a user never will and vice versa? Isnt that bad since the only columns they will share is name/email/password?

The User will have columns that pertain to them and their capabilities and the admin will have his own columns that are different and not shared.

Example a user will have an address, profile picture, phone number, etc. An admin wont have those but will have admin role, status, etc

martinbean's avatar

@rokkan As every one is suggesting: specify a role. Can be a simple as either member or admin. Admins are just users with special privileges.

With regards to things like addresses, telephone numbers etc, they usually go in a separate table. Addresses definitely should. Otherwise you’re going to end up with a users table with 50 columns if you put every in there.

pmall's avatar

The User will have columns that pertain to them and their capabilities and the admin will have his own columns that are different and not shared.

Create a table for each roles, with its specific columns and a user_id. User model is linked by these models with hasOne relationship.

rokkan's avatar

@pmall Oh so have a users table that then either point to a AdminInfo table that will have all the admin columns and a CustomerInfo table that will have all the customer columns.

So the Users table will just have name, email, password, role(Admin\Customer), roleId(Which id in the table from role) ??

martinbean's avatar

@rokkan You’re not reading properly. You don’t want a table per user type. Just have a generic users table, and give your user a role, whether that’s a column in the users table, or a separate table that maps users to roles in a roles table.

Stop thinking about admin- and customer-specific columns, they’re all users at the end of the day.

1 like
rokkan's avatar

@martinbean But without seperate tables there will be a lot of pointless columns for admins and a lot of pointless columns for customers. The ones that arent shared. I feel like thats inefficient and can be done better than just throwing all of it on one table

martinbean's avatar

@rokkan Again, you’re not reading. I clearly stated you would have different tables for things like addresses, rather than adding all of the needed columns to the one users table.

rokkan's avatar

@martinbean I understand but you will still need a column to point to the entry in Address table which is a pointless column for all admins... and so on for all customer unique coulmns

rokkan's avatar

@martinbean Very true. I see now how thats better for things like address where its multiple fields, you can just put in address table that has all address fields and the user its associated with. This cuts the multiple address fields into just 1 table.

What is your suggestion on fields that only contain 1 column, like age, dogs name, or nickname. Admins wont have these, customers will but isnt it a bit much to create a whole age table with 2 columns(age, user it belongs to) that points to user?

davorminchorov's avatar

I'd say check out the videos Users And Roles and ACL in Laravel: Roles And Permissions. These 2 videos will give you a lot of ideas on how to change your application design for the better.

Admin, Customer, Manager, Moderator, Regular Joe, and whatever else is usually a role for a user. All of these roles are just types of users. You don't need a new table for each role.

Also, they all share the same user profile info, it's just that different roles have different access levels to different parts of the application.

rokkan's avatar

@Ruffles I am watching those now lol. I understand about keeping users in same table. You say they all share the same user profile info but for my application they wouldnt. For example a user may have a age, and hair color. But an admin wont ever have those so it feels like a pointless column. I could make them seperate tables with foreign keys but then I have a table with just 1 column(ex: age) and the foreign key to point to the user. Is that the right direction?? Or have a user table with age and dog name and hair color with foreign key but then im clumping it?

I see the benifit of foreign keys when the table has more than 1 entry like address(street, city, state, country, zip). But when its just 1 (age) I'm confused if its the right direction

martinbean's avatar

@rokkan An administrator is a user. Users have profiles. Administrators don’t have to complete their profile. There’s no reason to separate them into two different types of users. What happens if you introduce moderators? Are you going to create a third model type? I hope not.

Just stick with a user model, a user has a profile, and a user also belongs to a role (which will make them either a regular user or a privileged user).

cimrie's avatar
cimrie
Best Answer
Level 4

@rokkan if you do feel that implementing them on separate tables is what you prefer, do that. You can have the User model (that uses 'users' table) contain a 'userable' polymorphic relation id and type - this points to either an underlying customer profile or admin profile. If you don't think you'll have many roles (say no more than a 'customer' and an 'admin') then this might be the best way for you.

Recommended video: https://www.youtube.com/watch?v=5DVDewOReoY then the follow up to that: http://adamwathan.me/2015/09/03/pushing-polymorphism-to-the-database/

You should also check out http://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations

It is quite an advanced topic, and on top of that an unusual use case of polymorphism but it definitely lends itself to it - I have used it to mask customer types in a system I am building.

pmall's avatar

I think it is totally fine to have a CustomerInfo model and an AdminInfo model to store things specific for customers and admins.

rokkan's avatar

@CImrie Those links helped a lot, thank you so much.

Any other great must watch links? lol

cimrie's avatar

@rokkan ,

Great to hear. Are you looking for things along the same line or just other videos I have found very useful?

masterpowers's avatar

@rokkan

Your Trying to Do This? This Wont WOrk in my Opinion

namespace App\Http\Middleware;

use Closure;
use App\Admin;

class AdminMiddleware
{

    public function handle($request, Closure $next)
    {
        if ($request->user() instanceof Admin)   // This Wont Work :)
        { 
            return $next($request);
        } else {
            return redirect('home');
        }

        return $next($request);
     }
}

BUt If you Want to Achieve SOmething Like this This is How I would do it.

Why not Use Multi Auth Since You Want Both User and Admin Model Be Interchangable... Im Using this https://github.com/wuifdesign/laravel-multiauth

Im Not the Author I just Love the Way it was Coded Since You Dont Have

Any Modification Needed Since it is Extending Your AuthController

Configuration is pretty easy too, take app/config/auth.php with its default values

Take Note The Table will be Determine in your Model File which is being extended by Eloquent in the multi array as driver

return array(

    'default' => 'user',
    'multi' => array(
        'admin' => array(
            'driver' => 'eloquent',  // This is What You Wanted to Have an Instance of the Model Using Auth of Laravel
            'model'  => Admins::class,
        ),
        'user' => array(
            'driver' => 'eloquent',
            'model'  => Users::class,
            'password' => [
                'email' => 'users.emails.password',
            ]
        )
    ),

    'password' => array(
        'email' => 'emails.password',
        'table' => 'password_reminders',
        'expire' => 60,
    ),
);

From Here You Can Create a Middleware Like So

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Guard;


class AdminAuthenticate
{
    /**
     * The Guard implementation.
     *
     * @var Guard
     */
    protected $auth;

    /**
     * Create a new filter instance.
     *
     * @param  Guard  $auth
     * @return void
     */
    public function __construct(Guard $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($this->auth->guest()) {
            if ($request->ajax()) {
                return response('Unauthorized.', 401);
            } else {
                return redirect()->guest('admin/auth/login'); // You Can Use Home Here if you wanted :)
            }
        }
        return $next($request);
    }
}



Note That i Have an AdminController that Extend the Default COntroller. To Use the Trait Already Implemented in AuthController So You Can Change the redirectpath loginpath and logoutpath

<?php

namespace App\Http\Controllers\Auth;


class AdminAuthController extends AuthController
{
    protected $redirectPath = '/admin/dashboard';
    protected $loginPath = '/admin/auth/login';
    protected $redirectAfterLogout = '/admin/auth/login';

    



    
    
}

Then in Route You can DO Something like this

$router->group(['auth' => 'user'], function() use ($router)
{
    $router->get('dashboard', function() {
        return 'User - Logged in as '.Auth::user()->email.' <a href="/auth/logout">Logout</a>';
    });
    $router->controller('auth', 'Auth\UserAuthController');
    $router->controller('password', 'Auth\UserPasswordController');
});

$router->group(['prefix' => 'admin', 'auth' => 'admin'], function() use ($router)
{
    $router->get('dashboard', function() {
        return 'Admin - Logged in as '.Auth::user()->email.' <a href="/admin/auth/logout">Logout</a>';
    });
    $router->controller('auth', 'Auth\AdminAuthController');
    $router->controller('password', 'Auth\AdminPasswordController');
});

If Your Authentication is Successful using the Default Out of the Box by Laravel Using the Route Above You Can Just Simple Use Auth->user()->name based on the route you use define by 'auth' in the router group array you can use either admin or user model.

The Best thing is you can Impersonate a User Instantly

Auth::impersonate(3, 'admin');

Here You Impersonate an Admin With a User ID of 3

Of Course on top of All You Should Have a Database Table for users and admins. But You are not Limited using anydatabase you can use multiple database.

<?php

namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;


class Admin extends Model implements AuthenticatableContract,
                                    AuthorizableContract,
                                    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword;

    /**
     * The database table used by the model.
     *
     * @var highlight_string(str)
     */
    protected $table = 'admins';
    protected $connection = 'mysql2'; // 2nd database set in config/database.php

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'email', 'password'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];
}

Let me Know if This Help :)

Next

Please or to participate in this conversation.