Laravel 5雄辩 - 将子字段添加到父模型

时间:2018-04-04 09:47:23

标签: php sql laravel-5 eloquent laravel-eloquent

我有一个用户模型,它有一个叫做老师的子关系。如何将相关教师模型中的字段添加到父用户模型返回的数据集中?

我希望返回的用户模型具有如下结构:

user.firstname

user.lastname

user.teacher.address

我尝试过使用以下内容及其变体,但没有成功:

            $query->select('firstname', 'lastname')
            ->addSelect( \DB::raw('teachers.address AS address') );

user.php模型:

    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模型:

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

这是我现有的查询,我遇到了问题:

        $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();

这是一个现有的应用程序,一切都按预期工作;我的问题更多是关于如何将子模型列添加为父模型的别名(然后我将使用新的别名列来计算某些内容)。

提前致谢,

...ķ

1 个答案:

答案 0 :(得分:0)

好的,我最终自己解决了这个问题。

我在我的用户模型中添加了一个范围:

    public function scopeJoinWithTeacher($query)
{
    return $query->leftJoin("teachers", "teachers.id", "=", "users.userable_id");
}

然后我在我的查询中实现了这个新范围,并在get()中从子模型到父模型实现别名列:

    $query = User::where('userable_type', 'App\Teacher');
    $query->with('userable');
    $query->whereDoesntHave('thisSchool');
    $query->JoinWithTeacher();
    $query->orderBy( 'distance', 'ASC' );

    $otherTeachers = $query->get(['teachers.longitude AS longitude', 'teachers.latitude AS latitude', 'users.*']);

我现在拥有来自eloquent返回的父模型中教师子关系的经度和纬度列。在我的具体情况下,我进一步使用这些别名字段来计算距离,并在我的用户模型中创建一个名为distance的新别名。

希望能帮助那些尝试同样事情的人!

...ķ