belongsTo(Student::class); } public function audition(): BelongsTo { return $this->belongsTo(Audition::class); } public function school(): HasOneThrough { return $this->hasOneThrough( School::class, Student::class, 'id', 'id', 'student_id', 'school_id'); } public function scoreSheets(): HasMany { return $this->hasMany(ScoreSheet::class); } public function advancementVotes(): HasMany { return $this->hasMany(JudgeAdvancementVote::class); } public function flags(): HasMany { return $this->hasMany(EntryFlag::class); } public function hasFlag($flag): bool { // return true if any flag in $this->flags has a flag_name of declined without making another db query if flags are loaded return $this->flags->contains('flag_name', $flag); } public function addFlag($flag): void { if ($this->hasFlag($flag)) { return; } $this->flags()->create(['flag_name' => $flag]); $this->load('flags'); } public function removeFlag($flag): void { // remove related auditionFlag where flag_name = $flag $this->flags()->where('flag_name', $flag)->delete(); $this->load('flags'); } /** * Ensures score_sheets_count property is always available */ public function getScoreSheetsCountAttribute() { if (! isset($this->attributes['score_sheets_count'])) { $this->attributes['score_sheets_count'] = $this->scoreSheets()->count(); } return $this->attributes['score_sheets_count']; } public function seat(): HasOne { return $this->hasOne(Seat::class); } public function scopeForSeating(Builder $query): void { $query->where('for_seating', 1); } public function scopeForAdvancement(Builder $query): void { $query->where('for_advancement', 1); } public function scopeAvailable(Builder $query): void { $query->whereDoesntHave('flags', function (Builder $query) { $query->where('flag_name', 'declined') ->orWhere('flag_name', 'no-show') ->orWhere('flag_name', 'failed-prelim'); }); } }