TechKat's avatar

Automatic Model::find() based on a user's column with ID.

Trying to make that title sound easy to understand.

Basically, I have 2 models here.

School.php User.php

School model reads from a database that holds information about a school. (Name, address, currency, etc)

The users table in the database contains a column called school, which contains the ID of the user's school in the School database table.

Throughout my application, the user will be reading the data from their school's database record, such as outputting the currency symbol that has been set for them.

At the moment, each time I need to use the School Model, I have to make an instance of it in the controllers, and use the ::findOrFail method, whilst passing in the user's school value into it.

Is there an easier way of doing this so that when I call the School Model as an instance, it automatically detects the ID from the user and has it all ready without having to repeat the code in every controller?

Apologies if that doesn't make sense. Trying to make it as simple as I can.

0 likes
5 replies
michaeldyrynda's avatar

You can define a school relationship on your user model and access it that way.

<?php

# app/User.php

namespace App;

use App\School;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function school()
    {
        return $this->belongsTo(School::class);
    }
}


# app/School.php

<?php

namespace App;

use App\User;
use Illuminate\Database\Eloquent\Model;

class School extends Model
{
    public function users()
    {
        $this->hasMany(User::class);
    }
}

Then in your controller, you can do the following:

public function show($user_id)
{
    $user = App\User::with('school')->find($user_id);

    return view('users.show', compact('user'));
}

For this to work, you should also name the school column school_id so Eloquent knows how to reference the school. If you're not able to do this for whatever reason, you'll need to add school as the second parameter of the belongsTo method in the User::school() method.

public function school()
{
    return $this->belongsTo(School::class, 'school');
}
TechKat's avatar

@deringer I forgot relationships existed, thanks for that!

Another quick question.

Besides the School and User models, I also have an Assets model, which speaks to a table that holds data about ICT assets. I want to use relationships with this and I have no idea how to go about this.

Basically what needs to happen is:

When the assets page is viewed, the controller will collect the records of assets based on the user's school.

Both the Assets and User tables each have the school_id column, which pretty much relates to the id of a School table record.

I can guarantee this is probably something so simple and I can't figure it out on my own.

michaeldyrynda's avatar

Just define a school method on the Asset and User model, which returns $this->belongsTo(School::class). As long as the assets and users tables have a school_id field in them, the relationships will behave themselves.

pmall's avatar

Relationships can be chained

  • School hasMany User / User belongsTo School
  • School hasMany Asset / Asset belongsTo School
Auth::user()->school->assets; // Return user's school assets collection

Please or to participate in this conversation.