2015-01-20 2 views
1

Im совершенно новый для Laravel, и у меня есть вопрос о том, как вы должны получать модели внутри моделей в Laravel. Например, модель A содержит n-номер модели B, содержит n-число модели C. aka. модель A hasMany model B hasMany model C.Laravel попасть внутрь get

Теперь мне нужно отобразить график в HTML, который включает данные из моделей A/B/C.

Пример кода

A::all()->each(function($A) 
{ 
    foreach($A->B()->get() as $B) 
    { 
     foreach($B->C()->orderBy("id", "desc")->get() as $C) 
     { 
      foreach($C['attributes'] as $attribute) 
      { 
       //Do stuff with attributes 
      } 
     } 
    } 
}); 

содержание A(), B(), C()

public function A() 
{ 
    return $this->hasMany('A'); 
} 

Вы видите вложенные циклы Foreach, каждый из которых делает запрос. Совсем не хорошо. Вы можете получить все это в одном выражении SQL. Мой вопрос будет в два раза.

1) Производит ли каждый метод get() запрос к базе данных или они генерируются при генерации класса? Laravel автоматически кэширует результаты запроса?

2) Я даже смотрю в правильном направлении, или мой код совершенно не так?

ответ

1

Во-первых, вместо того, чтобы использовать get() вы можете просто использовать функцию отношения, как это было свойство:

foreach($A->B as $B) 

Теперь вы правы с вступлением, в настоящее время каждый get() вызывает запрос. Способ исправления: eager loading. Это означает, что вы загружаете связь один раз для всех моделей, а затем вы просто обращаетесь к ним в памяти.

Это, как жадная загрузка работает одна связи:

A::with('B')->get(); 

Поскольку у вас есть вложенных отношения вы можете использовать «точку» синтаксис для нетерпеливых нагрузок всеми они сразу же:

A::with('B.C')->get(); 

И ваш полный код будет выглядеть так:

A::with('B.C')->get()->each(function($A){ 
    foreach($A->B as $B){ 
     foreach($B->C as $C){ 
      foreach($C['attributes'] as $attribute) 
      { 
       //Do stuff with attributes 
      } 
     } 
    } 
}); 

И не забудьте добавить orderBy к вашему соотношению:

public function C(){ 
    return $this->hasMany('C')->orderBy('id', 'desc'); 
} 

(Вы также можете сделать заказ по когда нетерпеливый нагрузки, передавая замыкание в with(), но я рекомендую вам сделать это в отношениях напрямую)

+0

Это место, отличный ответ! –

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