检查另一个表的字段状态雄辩


checking another table for a field status eloquent

好的,我有一个自定义字段名称is_friend

我有3张桌子
1. 用户
2. 工人
3. 朋友

正如你猜的那样,工作人员属于用户,朋友属于工作人员。

我的查询,我想检查工作人员是否是当前登录用户的朋友

好友架构:

    Schema::create('tweets', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('targetID');
        $table->integer('ownerID');
        $table->timestamps();
    }

从架构中可以看到,目标 ID 是工作人员的好友 ID,所有者 ID 是登录用户。

我的查询:

$worker = Worker::get('name');

在我的工人模型内

class Worker extends Eloquent{
    protected $appends = array('is_friend');
    public function user(){
        return $this->belongsTo('user');
    }
    public function getIsFriendAttribute(){
        if(Friend::where('targetID', $this->attributes['id'])
            ->where('ownerID', Auth::user()->id)->first()){
            return true;
        } else {
            return false;
        }
    }
}

我正在使用自定义访问器来获取此自定义字段。它可以工作,但它很丑陋,如果我查询 20 个工人,将有 20 个查询来检查此状态。

在视图上,我可以像

@if($worker->is_friend)
   Your friend
@endif
好的,

我认为这个问题(n+1 问题(可以使用带有约束的预先加载来解决。

首先在工作线程模型中定义一个好友关系。因此

class Worker extends Eloquent{
    ...
    // This will get all the friends
    public function friends(){
        return $this->hasMany('Friend','targetID');
    }
    ...
}

我们使用急切加载来处理 n +1 问题。单击此处并向下滚动到文档的预先负载约束

// We use Eager loading constraints so that only two db queries are executed instead of n+1
$workers = Worker::with(array('friends' => function($query)
{
    // So we constraint the ownerId to be current user id
    $query->where('ownerID', Auth::user()->id);
}))->get();

现在在视图上

@foreach ($workers as $worker)
    @if(count($worker->friends) >0)
    Your friend
    @endif
@endforeach

您可以向Worker模型添加以下关系:

public function friendsNumber()
{
    return $this->hasMany('Friend','targetID')
        ->selectRaw('targetID, count(targetID) as count')
        ->where('ownerID', Auth::user()->id)
        ->groupBy('targetID');            
}

现在将以下访问器添加到Worker模型:

public function getIsFriendAttribute()
{
    if (!array_key_exists('friendsNumber', $this->relations)) {
        $this->load('friendsNumber');
    }
    $related = $this->getRelation('friendsNumber')->first();
    return ($related && $related->count) ? true : false;
}

现在您应该能够使用:

$workers = worker::with('friendNumber'(->get((;

foreach ($workers as $worker) {
  echo $worker->name;
  if ($worker->is_friend) {
     echo " is your friend";
  }
  echo "<br />";
}