2017-11-22 4 views
0

Ich erstelle eine Schulplattform, wo Schüler, Lehrer, ... mit ihren Anmeldeinformationen anmelden können. Um doppelte Daten zu reduzieren, habe ich keine separate Tabelle namens students erstellt, stattdessen behalte ich alle Daten in der users-Tabelle.Make eloquent Modell für Untertyp

Um zu wissen, ob ein Benutzer ein Student mir eine Tabelle, die Einschreibungen genannt wird, in dieser Tabelle ein user_id, schoolyear_id und class_id gespeichert sind.

Ich habe bereits ein Schülermodell erstellt, das auf die Benutzertabelle verweist, aber wie kann ich sicherstellen, dass dieses Modell nur Schüler durchlässt?

EER: EER overview

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); 
    } 

} 

Was ich will, erreichen, ist, dass, wenn ich rufe die Student::all(); Funktion, die ich alle bekommen die Benutzer, die an der Schule eingeschrieben sind, also Studenten.

Antwort

1

Ihre bereitgestellte Lösung führt mich in die richtige Richtung. Mein Problem wurde durch die Verwendung des globalen Gültigkeitsbereichs gelöst:

<?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); 
    } 

} 
1

Check-out-Modell Ereignisse: https://laravel.com/docs/5.5/eloquent#events

sollten Sie in der Lage sein, dies für einen Test in Ihr Studentenmodell fallen zu lassen:

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

Ich bin immer noch auf 5,4, die nicht das abgerufene Modell hat Ereignis eingebaut, aber die Rückgabe von false stoppt den Anruf im Allgemeinen. Wenn diese Logik auf das abgerufene Ereignis angewendet wird, kann diese Modellinstanz möglicherweise nicht zurückgegeben werden, wenn es sich nicht um einen Schüler handelt, sondern die Schüler können zurückgegeben werden. Nur ein Gedanke.

Verwandte Themen