Laravel eloquent - готовность к загрузке вложенных отношений - PullRequest
0 голосов
/ 24 января 2020

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

  • Сообщения
  • Комментарии
  • Метки

Сообщения:

    class Post extends Eloquent
    {

        public function comments()
        {
            return $this->hasMany(Comment::class,'post_id','id');
        }

    }

    ** Post data **
    {
       'id' : 1,
       'title' : 'bla bla',
       'created_at: 'some date'
    }

Комментарии:

    class Comment extends Eloquent
    {

        public function comments()
        {
            return $this->belongsTo(Post::class,'id');
        }

        public function tags()
        {
            return $this->hasMany(Tag::class,'id','tags_ids');
        }

    }

** Comments data **

    {
      'id' : 322,
      'active' : true
      'post_id' : 1,
      'created_at: 'some date',
      'tags_ids' : [1,2,3]
    }

Теги:

    class Tag extends Eloquent
    {

        public function tags()
        {
            return $this->belongsTo(Comment::class,'tags_ids');
        }

    }

    ** Tags data **
    {
      {'id' : 1,
      'description' : 'some description1'
      },
      {'id' : 2,
      'description' : 'some description2'
      },
      {'id' : 3,
      'description' : 'some description3'
      }
    }

В таблице записей много комментариев, а в таблице комментариев - много тегов.

Как мне собрать все эти таблицы вместе, используя готовую загрузку?

Что-то вроде:

$post = Post::where('id',1)->with(['comments' => function($q) {
   $q->with('tags');
}])->first();

, но этот запрос всегда возвращает пустой ответ в отношении тегов.

Что я делаю неправильно ?

Желаемый результат выглядит примерно так:


{
   'id' : 1,
   'title' : 'bla bla',
   'created_at: 'some date',
   'comments':[{
                  'id' : 322,
                  'active' : true
                  'post_id' : 1,
                  'created_at: 'some date',
                  'tags_ids' : [1,2,3],
                  'tags' : [
                            {'id' : 1,'description' : 'some description1'},
                            {'id' : 2,  'description' : 'some description2'},
                            {'id' : 3,'description' : 'some description3'}
                           ],
              }
             ]
}

Вы можете видеть, что пост содержит комментарии внутри него, а также комментарии содержат теги внутри него.

PS Я использую пакет 'jenssegers / laravel -mongodb' в своем проекте и пытаюсь сделать это без какого-либо необработанного выражения.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 24 января 2020

Вы неправильно определили свои отношения. У вас есть tags_ids как массив в вашей модели комментариев, но вместо этого вам нужны отношения многие ко многим для ваших тегов. Чтобы реализовать это, вы должны определить новую таблицу comment-tag:

comment-tag
    comment_id - unsined big integer
    tag_id - unsigned big integer

Тогда в вас Comment модель изменить tags отношения, как это:

class Comment extends Model
{
    /**
     * The tags that belong to the comment.
     */
    public function tags()
    {
        return $this->belongsToMany('App\Tag');
    }
}

Обратное это соотношение:

class Tag extends Model
{
    /**
     * The comments that belong to the tag.
     */
    public function comments()
    {
        return $this->belongsToMany('App\Comment');
    }
}

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

$post = Post::with(['comments', 'comments.tags'])->find(1);

См. Отношение «многие ко многим» Laravel документов для получения дополнительной информации.

1 голос
/ 24 января 2020

вы можете использовать

$post = Post::where('id',1)->with(['comments.tags'])->first();

, он будет загружать все комментарии, а также comments.tags

ссылка ref https://laravel.com/docs/6.x/eloquent-relationships в поиске ссылок Nested Eager Loading

0 голосов
/ 24 января 2020

ОБНОВЛЕНИЕ: Вы должны исправить свою схему БД

Структура таблицы выглядит следующим образом:

- posts
    - id
    - title
    - ...

- comments
    - id
    - active
    - post_id 
    - created_at

- tags
    - id
    - description
    - comment_id 
    - created_at

// App\Post 
class Post extends Eloquent 
{

    public function comments()
    {
        return $this->hasMany(Comment::class,'post_id','id');
    }

}

// App\Comment 
class Comment extends Eloquent 
{

    public function post()
    {
        return $this->belongsTo(Post::class);
    }

    public function tags()
    {
        return $this->hasMany(Tag::class);
    }

}


//App\Tag    
class Tag extends Eloquent 
{

    public function comment()
    {
        return $this->belongsTo(Comment::class);
    }

}




//...
$post = Post::with(['comments', 'comments.tags'])->find(1);
//...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...