为子类型制作 eloquent 模型
Make eloquent model for subtype
我正在创建一个学校平台,学生、教师......可以使用他们的凭据登录。为了减少重复数据,我没有单独创建一个名为 students 的 table,而是将所有数据保留在 users table.
中
要知道用户是否是学生,我有一个称为注册的 table,在此 table 中有 user_id
、schoolyear_id
和 class_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);
}
}
我正在创建一个学校平台,学生、教师......可以使用他们的凭据登录。为了减少重复数据,我没有单独创建一个名为 students 的 table,而是将所有数据保留在 users table.
中要知道用户是否是学生,我有一个称为注册的 table,在此 table 中有 user_id
、schoolyear_id
和 class_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);
}
}