2014-12-20 2 views
2

Хорошо у меня есть имя настраиваемого поля is_friendпроверка другой таблицы для состояния поля красноречивого

У меня есть 3 таблицы
1. Пользователи
2. Рабочие
3. Друзья

Как вы догадываетесь работник принадлежит пользователю, друг принадлежит рабочему.

Мой запрос, я хочу, чтобы проверить, является ли если работник друг тока, подписанного в пользователь

Друзья схемы:

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

Как видно из схемы, то targetID является идентификатором друга рабочего, ownerID является подписанным пользователем.

Мой запрос:

$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 
+0

Как вы запрашиваете 20 сотрудников? –

+0

Здравствуйте, @ MarcinNabiałek, теперь я делаю 'Worker :: get ('name')', он получит все строки рабочего стола, так как я не использую никаких ограничений или где. Поэтому, если есть 20 строк, будет выведено 20, таким образом, еще 20, чтобы проверить каждую строку для этого состояния. – edward

+0

Существует метод hasManyThrough для такого рода отношений, но я не уверен, выполнит ли он то, что вы хотите. Я отправлю ответ, если я смогу проверить его в ближайшее время. – Hkan

ответ

1

OK Я думаю, что эта проблема (проблема с n + 1) может быть решена с использованием надежной загрузки с ограничениями.

Сначала определите отношение друзей в рабочей модели. как таковой

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

} 

Мы используем жадную загрузку, чтобы иметь дело с п +1 проблемы. Click here and scroll down to Eager Load Constraints for documentation

// 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 
+0

спасибо за ответ, у меня есть вопрос, если я использую это, будут получены только рабочие с друзьями? как насчет тех, у кого нет друзей. Я хочу получить смешанные результаты работы, которые дружат с пользователем, а не. и если они друзья, то будет поле для его идентификации. – edward

+0

ах nvm это, это работает. большое спасибо – edward

1

Вы можете добавить следующее отношение к вашей 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; 
} 

Теперь вы должны быть в состоянии нам e:

$ workers = Рабочий: с ('friendNumber') -> get();

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

Не существует метода 'count' на' $ related', который называется так: либо проверяйте только на 'null', либо не используйте строку' first' выше. ** Или ** используйте 'hasOne', а не, конечно. –

Смежные вопросы