好的,我有一个自定义字段名称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 />";
}