I have a user model which has a child relationship called teacher. How can I add a field from the related teacher model to the dataset returned of the parent user model?
I would like the user model returned to have a structure like below:
user.firstname
user.lastname
user.teacher.address
I have tried using the following and variations thereof with no success:
$query->select('firstname', 'lastname')
->addSelect( \DB::raw('teachers.address AS address') );
user.php model:
use Notifiable;
use SoftDeletes;
use EncryptableTrait;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'title',
'firstname',
'firstname_h',
'lastname',
'lastname_h',
'email',
'email_h',
'password',
'userable_id',
'userable_type'
];
/**
* The attributes that are mass encryptable, using the EncryptableTrait.
*
* @var array
*/
protected $encryptable = [
'firstname',
'lastname',
'email',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function userable()
{
return $this->morphTo();
}
public function teacher() // Using custom BelongsToMorph relationship type
{
return BelongsToMorph::build($this, Teacher::class, 'userable');
}
public function roles()
{
return $this->belongsToMany('App\Role')->withTimestamps();
}
public function schools()
{
return $this->belongsToMany('App\School')->withPivot('suspended', 'rating');
}
public function thisSchool()
{
return $this->belongsToMany('App\School')->where('school_id', Auth::user()->userable->id)->withPivot('id', 'suspended', 'rating', 'notes');
}
public function addRole($user, $role_id)
{
$user->roles()->attach($role_id);
}
public function removeRole($user, $role_id)
{
$user->roles()->detach($role_id);
}
public function isAdmin($user)
{
foreach ($user->roles as $role) {
if($role->id == 4) {
return true;
} else {
$return = false;
}
}
return $return;
}
public function isSchoolAdmin($user)
{
foreach ($user->roles as $role) {
if($role->id == 2) {
return true;
} else {
$return = false;
}
}
return $return;
}
public function events()
{
return $this->belongsToMany('App\Event')->withPivot('cancelled', 'cancelled_by');
}
public function devices()
{
return $this->hasMany('App\Device');
}
public function teachingstages()
{
return $this->belongsToMany('App\Teachingstage', 'teacher_teachingstage')->orderBy('teachingstage_id');
}
public function teachingsubjects()
{
return $this->belongsToMany('App\Teachingsubject', 'teacher_teachingsubject');
}
teacher.php model:
use EncryptableTrait;
protected $table = "teachers";
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'mobile',
'dob',
'gender',
'address',
'postcode',
'latitude',
'longitude',
'max_distance',
'public',
'photo',
'experience',
'active',
'verified',
'payscale',
'ta_number',
'temp_or_perm',
'locked'
];
/**
* The attributes that are mass encryptable, using the EncryptableTrait.
*
* @var array
*/
protected $encryptable = [
'mobile',
'address',
'postcode',
'experience',
'ta_number'
];
public function user()
{
return $this->morphOne('App\User', 'userable');
}
public function criterias()
{
return $this->hasMany('App\Criteria');
}
public function bookingrequests()
{
return $this->belongsToMany('App\Bookingrequest')->withPivot('sent', 'sent_at', 'declined', 'created_at', 'updated_at');
}
public function blacklist()
{
return $this->hasMany('App\Blacklist');
}
This is my existing query that I am having issues with:
$query = User::where('userable_type', 'App\Teacher');
$query->with('userable');
$query->select('firstname', 'lastname')
->addSelect( \DB::raw('teachers.address AS address') );
$query->whereDoesntHave('thisSchool');
$otherTeachers = $query->get();
This is an existing app and everything works as expected; my question is more about how I can add a child model column as an alias to the parent model (I will then use the new alias columns to calculate something).
Thanks in advance,
K...
OK, I worked this out myself in the end.
I added a scope to my user model:
I then implemented this new scope in my query and aliased columns from child to parent model in the get():
I now have the longitude and latitude columns from the teacher child relation in my parent model returned from eloquent. In my specific case, I then go further to use these alias fields to calculated distance and create a new alias called distance in my user model.
Hope that helps somebody who was attempting the same thing!
K...