Laravel eloquent - отношения один ко многим

Я только начал работать с laravel v3 и пытаюсь осмыслить отношения красноречивого «один ко многим», создав блог, у меня есть сообщения, которые имеют отношение «многие к одному» с категориями (каждое сообщение связано с категорией).

У меня есть следующие таблицы со следующими полями:

сообщения: id, title, body, date_created, category_id

категории: идентификатор, имя

У меня две модели:

class Category extends Eloquent 
{
    public function posts()
    {
        return $this->has_many('Post');
    }
}

class Post extends Eloquent 
{
    public function categories()
    {
        return $this->belongs_to('Category');
    }
}

Я понял, как получить все сообщения, передав идентификатор категории:

category::find(2)->posts()->get())

Мне просто нужна помощь в том, чтобы узнать, как получить все сообщения и соответствующие категории. Итак, в конце дня в представлении я могу вывести что-то вроде этого:

{$post->title} -  Category: {$post->category->name}

Спасибо за любую помощь!


person Allister    schedule 17.10.2012    source источник
comment
Я думаю, вы ищете Активную загрузку.   -  person Robert K    schedule 17.10.2012


Ответы (2)


Надеюсь, эти советы вам пригодятся.

В модели поста переименуйте функцию categories в category. Отношение belongs_to является единичным, поэтому у этого поста одна и только одна категория.

Отношения также имеют краткую формулировку, этот сокращенный синтаксис полезен, поскольку его проще использовать, а результаты кэшируются. Вот пример:

$category = Category::find(1);
foreach($category->posts as post) {
    echo $post->title;
}

Теперь пример того, как получить все сообщения с соответствующими категориями:

$posts = Post::all();
foreach($posts as $post) {
    echo $post->category->name;
}

При выполнении этого второго примера вы быстро заметите увеличение количества запросов для каждой публикации. Это называется эффектом N + 1. Например, если у вас 5 сообщений, для их получения будет выполнен один запрос. Затем в цикле мы выполняем запрос, чтобы получить категорию. В результате получается 6 запросов.

Чтобы решить эту проблему, используйте активную загрузку, которая сокращает эти 6 запросов в нашем примере до 2.

$posts = Post::with('category')->all();
foreach($posts as $post) {
    echo $post->category->name;
}

Надеюсь, это поможет!

person William Cahill-Manley    schedule 17.10.2012
comment
Спасибо, Уильям, это именно то, что мне нужно! - person Allister; 18.10.2012
comment
Надеюсь, что то же самое и с Laravel 4. У меня есть одно небольшое сомнение. Я новичок в этом. Можете ли вы сказать, нужно ли вводить эту нетерпеливую загрузку в контроллер / представление? - person harishannam; 11.07.2013
comment
Обычно это делается в контроллере или в классе-оболочке, известном как репозиторий, который используется контроллером. Вы никогда не должны делать это в поле зрения. Насколько я могу судить, все это осталось неизменным в L4. - person William Cahill-Manley; 12.07.2013

Laravel 4 имеет немного другой синтаксис, он использует camelCase для построения выражений (в то время как L3 использует синтаксис snake_Case). Новый синтаксис Laravel (L4) теперь совместим с PSR-1.

L3 : $this->belongs_to('Category');
L4 : $this->belongsTo('Category');

Чтобы доказать, что «жадная загрузка» повышает производительность вашего приложения (за счет минимизации запросов к базе данных), используйте экосистему событий Laravel.

// app/routes.php 
Event::listen('illuminate.query', function($sql) { echo '<h4>' . $sql . '</h4>' ;});

.

person JohnD    schedule 08.08.2013