为子类型制作 eloquent 模型

Make eloquent model for subtype

我正在创建一个学校平台,学生、教师......可以使用他们的凭据登录。为了减少重复数据,我没有单独创建一个名为 students 的 table,而是将所有数据保留在 users table.

要知道用户是否是学生,我有一个称为注册的 table,在此 table 中有 user_idschoolyear_idclass_id 被存储。

我已经制作了一个引用用户table的学生模型,但是如何确保这个模型只通过学生?

能效比:

Student.php:

<?php

namespace App;

class Student extends User
{
    protected $table= 'users';

    public function enrollments(){
        return $this->belongsToMany(Enrollment::class);
    }
}

User.php:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Support\Facades\Auth;

class User extends Authenticatable
{
    use Notifiable;
    use HasRoles;

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

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function profiles(){
        return $this->hasOne(Profile::class);
    }

}

我想要实现的是,当我调用 Student::all(); 函数时,我得到了所有在学校注册的用户,因此得到了学生。

查看模型事件:https://laravel.com/docs/5.5/eloquent#events

您应该可以将其放入您的学生模型中进行测试:

protected static function boot(){
        parent::boot();
        static::retrieved(function($thisModel){
            if($thisModel->isNotAStudent or whatever logic you need){
                  return false;
            }
        }
    }

我仍在使用 5.4,它没有内置检索到的模型事件,但返回 false 通常会停止调用。因此,将该逻辑应用于检索到的事件可能会阻止返回该模型实例(如果它不是学生),但允许返回学生。只是一个想法。

您提供的解决方案引导我朝着正确的方向前进。我的问题已通过使用全局范围解决:

<?php

namespace App;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;

class Student extends User
{

    protected $table= 'users';

    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('student', function (Builder $builder) {
            $builder->whereExists(function ($query) {
                $query->select(DB::raw(1))
                    ->from('enrollments')
                    ->whereRaw('enrollments.user_id = users.id');
            });
        });
    }

    public function enrollments(){
        return $this->belongsToMany(Enrollment::class);
    }

}