2015-09-26 3 views
2

Использование Laravel Eloquent и отношения hasOne() \ hasMany(), возможно ли ограничить таблицу «родительский» только получением результатов, если «дочернее \ чужое» отношение существует?Laravel Eloquent hasMany hasOne ограничение родителей для детей с записями

Foos

+----+------------+ 
| id |  etc | 
+----+------------+ 
| 1 |  one | 
| 2 |  two | 
| 3 |  three | 
| 4 |  four | 
+----+------------+ 

БАРС

+----+-----+--------+ 
| id | val | foo_id | 
+----+-----+--------+ 
| 11 | 101 |  1 | 
| 12 | 102 |  2 | 
| 13 | 203 |  3 | 
| 14 | 204 |  4 | 
+----+-----+--------+ 

в классе Foo (модель)

public function highBars(){ 
    return $this->hasOne('App\Bar')->where('val','>','200'); 
} 

в контроллере

Foo::with('highBars')->get(); 

возвращает ВСЕ FOOS, хотя некоторые отношения high_bars равны нулю. Можно ли включать только результаты FOOS, значение отношения которых не равно нулю? (Foos.id = 3,4)

Это извлекается ...

0 => array:3 [▼ 
    "id" => 1 
    "etc" => "one" 
    "high_bars" => null 
    ] 
    1 => array:3 [▼ 
    "id" => 2 
    "etc" => "two" 
    "high_bars" => null 
    ] 
    2 => array:3 [▼ 
    "id" => 3 
    "etc" => "three" 
    "high_bars" => array:2 [▼ 
     "id" => 13 
     "val" =>203 
     "foo_id" =>3 
    ] 
    ] 
    3 => array:3 [▼ 
    "id" => 4 
    "etc" => "four" 
    "high_bars" => array:2 [▼ 
     "id" => 14 
     "val" =>204 
     "foo_id" =>4 
    ] 
    ] 

Но это то, что я хочу ..

0 => array:3 [▼ 
    "id" => 3 
    "etc" => "three" 
    "high_bars" => array:2 [▼ 
     "id" => 13 
     "val" =>203 
     "foo_id" =>3 
    ] 
    ] 
    1 => array:3 [▼ 
    "id" => 4 
    "etc" => "four" 
    "high_bars" => array:2 [▼ 
     "id" => 14 
     "val" =>204 
     "foo_id" =>4 
    ] 
    ] 
+1

Другие ответы ответить на вопрос (вы ищете 'имеет()', но я хотел бы отметить, что, так как 'Foo' содержит внешний ключ 'bar_id', отношение состоит в том, что' Foo' принадлежит 'Bar', тогда как' Bar' имеет один (или много) 'Foo'. – patricus

+0

Вы правы @patricus, я был сонлив, когда писал это и реализовано, когда оно было применено этим утром, что-то не было правильно. – dangel

ответ

1

Цитирую documentation.

При обращении к записям модели вы можете ограничить свои результаты, основанные на существовании отношений. Например, представьте себе , вы хотите получить все сообщения в блоге, содержащие хотя бы один комментарий. Чтобы сделать это, вы можете передать имя отношения к имеют метод:

// Retrieve all posts that have at least one comment... 
$posts = App\Post::has('comments')->get(); 

Вы также можете указать оператор и рассчитывать для дальнейшей настройки запроса:

// Retrieve all posts that have three or more comments... 
$posts = Post::has('comments', '>=', 3)->get(); 

Вложенные операторы могут также быть построены с использованием «точечной» нотации. Например, вы можете получить все сообщения, которые имеют по крайней мере один комментарий и голосовать:

// Retrieve all posts that have at least one comment with votes... 
$posts = Post::has('comments.votes')->get(); 

Если вам нужно еще больше мощности, вы можете использовать whereHas и orWhereHas методы поставить «, где «условия для ваших запросов.Эти методы позволяют добавлять собственные ограничения в отношениях ограничения, , такие как проверка содержание комментария:

// Retrieve all posts with at least one comment containing words like foo% 
$posts = Post::whereHas('comments', function ($query) { 
    $query->where('content', 'like', 'foo%'); 
})->get(); 

Ответ

Для вашего конкретного примера, это будет достигнуто с помощью:

Foo::has('highBars')->get(); 
+0

Использование 'Foo :: has ('highBars') -> get();' также не извлекает отношения, а используя 'Foo :: has ('highBars') -> с ('Bars') -> get(); 'ret снова получает все результаты. поэтому используется 'Foo :: has ('highBars') -> с ('highBars') -> get();' correct? кажется излишним – dangel

0

Этого недостаточно. Когда вы определили свое отношение, просто сообщите Laravel, какие данные связаны с сущностью, но это не ограничивает, как извлекаются данные.

Так что, когда вы будете делать в контроллере

Foo::with('highBars')->get(); 

ключ здесь это get. Вы никоим образом не ограничиваете это, вы просто говорите, получите мне все строки, которые у вас есть, и в дополнение к этому получите данные, связанные с этой моделью. Что вам нужно сделать, так это добавить, а также ограничение.

Foo::with('highBars')->whereHas('highBars', function ($query) { 
    $query->where('val', '>', '200'); 
})->get(); 

Или ярлык для этого будет

Foo::has('highBars')->get(); 
Смежные вопросы