首先,您需要您的外键为nullable,您可以在用户的migration 文件中指定:
your_migration_file.php
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
// your columns
$table->unsignedBigInteger('coach_id')->nullable(); // <-----
}); // ^^^^^^^^^^^^
}
请注意,这样做您将无法添加数据库约束,但无论如何这都不是必需的。另外,您可能需要refresh your migrations。
然后在您的User 模型中,您需要定义您的关系:
User.php
class User extends Model {
/** a Runner has a Coach. */
public function coach()
{
return $this->belongsTo(User::class, 'coach_id');
}
/** a Coach teaches many Runners */
public function runners()
{
return $this->hasMany(User::class, 'coach_id');
}
然后您可以对eager load 进行查询并限制结果:
YourController.php
public function myCoolFunction()
{
$runners = User::with('coach')->whereNotNull('coach_id')->get();
$coaches = User::with('runners')->whereNull('coach_id')->get();
}
当然,这些查询看起来很难看,所以你也可以在 User 模型中定义 local query scopes:
class User extends Model {
// some code..
public function scopeCoaches($query)
{
return $query->hasRole('coach'); // maybe you use a role package?
// return $query->whereNull('coach_id'); // or my basic approach used before
}
public function scopeRunners($query)
{
return $query->hasRole('srunner'); // maybe you use a role package?
// return $query->whereNotNull('coach_id'); // or my basic approach used before
}
}
然后只需使用您的范围:
public function myCoolFunction()
{
$runners = User::with('coach')->coaches()->get();
$coaches = User::with('runners')->runners()->get();
}