Полный цикл в digital

Связь один ко многим

Давайте теперь изучим связь один ко многим. Такая связь образуется, когда запись одной таблицы соответствует многим записям из другой таблицы.

Давайте посмотрим на примере. Пусть у нас есть следующая таблица с категориями:

category
        id
        name

Пусть также у нас есть следующая таблица с постами:

posts
        id
        title
        category_id

Заюзаем в модели с категориями модель с постами:

app/Models/Category.php<?php
use App\Models\Post;

class Category extends Model
{
    
}

Каждая категория имеет много постов, которые ссылаются на нее. Давайте в модели с категориями сделаем метод для получения постов:

app/Models/Category.php<?php
use App\Models\Post;

class Category extends Model
{
    public function posts()
    {
        
    }
}

Пропишем в этом методе связь через отношение hasMany:

app/Models/Category.php<?php
class Category extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

Получение данных

Выше мы связали категории и их посты отношением hasMany. Давайте теперь в контроллере получим какую-нибудь категорию:

app/Http/Controllers/CategoryController.php<?php
class CategoryController extends Controller
{
    public function show()
    {
        $category = Category::find(1);
        dump($category);
    }
}

Вместе с категорией мы автоматически получим коллекцию постов:

app/Http/Controllers/CategoryController.php<?php
class CategoryController extends Controller
{
    public function show()
    {
        $category = Category::find(1);
        dump($category->posts); // коллекция постов
    }
}

Давайте переберем коллекцию с постами через цикл:

app/Http/Controllers/CategoryController.php<?php
class CategoryController extends Controller
{
    public function show()
    {
        $category = Category::find(1);
        
        foreach ($category->posts as $post) {
            dump($post->title);
        }
    }
}

Давайте теперь получим коллекцию категорий. Переберем ее циклом, для каждой категории получим коллекцию постов и также переберем ее циклом:

app/Http/Controllers/CategoryController.php<?php
class CategoryController extends Controller
{
    public function show()
    {
        $categories = Category::all();
        
        foreach ($categories as $category) {
            dump($category->name);
            
            foreach ($category->posts as $post) {
                dump($post->title);
            }
        }
    }
}

Условия

Можно добавлять дополнительные условия при получении связанных данных. Давайте посмотрим, как это делается. Пусть у нашей таблицы с постами будет также и поле likes, содержащее количество лайков:

posts
    id
    title
    likes
    category_id

Давайте для начала получим категорию вместе с коллекцией ее постов:

app/Http/Controllers/CategoryController.php<?php
class CategoryController extends Controller
{
    public function show()
    {
        $posts = Category::find(1)->posts;
        dump($posts);
    }
}

Теперь заменим свойство posts на метод posts(). В этом случае метод своим результатом вернет построитель запросов:

app/Http/Controllers/CategoryController.php<?php
class CategoryController extends Controller
{
    public function show()
    {
        $qb = Category::find(1)->posts();
        dump($qb);
    }
}

Так как возвращается построитель запросов, то мы можем дальше продолжить цепочку, к примеру, наложив некоторое условие на получаемые посты:

app/Http/Controllers/CategoryController.php<?php
class CategoryController extends Controller
{
    public function show()
    {
        $posts = Category::find(1)
            ->posts()
            ->where('likes', '>', 10)
            ->get();
        
        dump($posts);
    }
}

Обратная связь

Пусть у нас опять есть таблица с категориями и таблица с постами. Выше мы говорили, что каждая категория имеет много постов. Но это зависит от точки зрения.

Если посмотреть со стороны поста, то каждый пост принадлежит одной категории. Это значит что пост можно связать с категорией отношением belongsTo:

app/Models/Post.php<?php
class Post extends Model
{
    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}

Получим теперь пост вместе с его категорией:

app/Http/Controllers/PostController.php<?php
class PostController extends Controller
{
    public function show()
    {
        $post = Post::find(1);
        dump($post);
        dump($post->category);
    }
}

Получим все посты, переберем их циклом и выведем их вместе с их категориями:

app/Http/Controllers/PostController.php<?php
class PostController extends Controller
{
    public function show()
    {
        $posts = Post::all();
        
        foreach ($posts as $post) {
            dump($post);
            dump($post->category);
        }
    }
}

Несколько обратных связей

Может такое быть, что одна таблица имеет несколько связей. Давайте посмотрим, как действовать в таком случае.

Пусть у нас есть таблица с постами:

posts
    id
    title

Таблица с юзерами:

users
    id
    name

Пусть у нас есть таблица с комментами, в который каждый коммент связан со своим постом и со своим юзером:

comments
    id
    text
    post_id
    user_id

Давайте пропишем эту связь в модели для комментов:

app/Models/Comment.php<?php
class Comment extends Model
{
    public function post()
    {
        return $this->belongsTo(Post::class);
    }
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

Теперь при получении коммента мы можем получить его пост и его юзера:

app/Http/Controllers/CommentController.php<?php
class CommentController extends Controller
{
    public function show()
    {
        $comment = Comment::find(1);
        dump($comment);
        dump($comment->post);
        dump($comment->user);
    }
}
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг