Проблема с получением комментариев, ответов и дочерних ответов поста - PullRequest
2 голосов
/ 26 сентября 2019

Создание приложения в виде миниинстаграммы, где у нас есть рекомендации (посты) и пользователи, которые могут их комментировать.Получение данных через API.И у меня проблема с получением всех комментариев и всех ответов определенного поста.

У меня есть таблица базы данных

comment
-------------------------------
|id                           |
|text(comment text)           |
|recommendation_id(post_id)   |
|user_id(author)              |
|parent_id(parent comment id) |
-------------------------------

Здесь, в parent_id, мы можем установить идентификатор родительского комментария.Комментарии имеют ответы и ответы также имеют ответы.Вот модель комментария

class Comment extends Model
{
    protected $with = ['user:id,name'];
    protected $table = 'comments';
    protected $fillable = ['text','user_id','recommendation_id'];



    public function recommendation()
    {
        return $this->belongsTo('App\Models\MobileApp\Recommendation' , 'recommendation_id');
    }
    public function user()
    {
        return $this->belongsTo('App\User');
    }
    public function replies()
    {
        return $this->hasMany('App\Models\MobileApp\Comment' ,'parent_id');
    }
    public function parent()
    {
        return $this->belongsTo('App\Models\MobileApp\Comment' ,'id');
    }
}

и модель рекомендации

class Recommendation extends Model
{
    protected $table = 'recommendations';
    protected $fillable = ['course_id','title','description','file'];

    public function comments()
    {
        return $this->hasMany('App\Models\MobileApp\Comment')->where('parent_id', '=', Null);
    }
}

А вот индекс метода рекомендации контроллера

public function index()
    {
        $recommendations = Recommendation::all();
        foreach($recommendations as &$item){
            //changing to full path
            $item['file'] = 'https://example.com/' . $item['file'];
            //getting comments
            $item['comments']=$item->comments;
           //getting replies
            foreach($item->comments as $alphabet => $collection) {
                 $collection->replies;
//if reply array not empty then look for child repliese. I should have here recursive 
                    if($item->comments[$alphabet]->replies->count()>0){
                    foreach($item->comments[$alphabet]->replies as $alphabet => $collection) {
                        $collection->replies;
                    }
                }
            }

        }
        if ($recommendations)
        {
            $response = ['success'=>true, 'data'=>$recommendations];
        }
        else
            $response = ['success'=>false, 'data'=>'Record doesnt exists'];


        return $response;
    }

Проблема в том, что если я получаю не пустой ответ, то янадо искать ответы детей.У меня должно быть что-то вроде рекурсии.Как я могу это сделать?

1 Ответ

2 голосов
/ 26 сентября 2019

Ваш код должен выглядеть примерно так:

Контроллер:

    ...

    public function index()
    {
        $recommendations = Recommendation::with([
            'comments.user',
            'comments.replies.user'
        ])->paginate(10);

        foreach ($recommendations as $item) {

            foreach ($item->comments as $comment) {
                // I have moved your code to load `replies` in model
                $comment->loadRecursiveReplies();
            }

        }

        if (!$recommendations->isEmpty()) {
            $response = ['success' => true, 'data' => $recommendations->toArray()];
        } else {
            $response = ['success' => false, 'data' => 'Record doesnt exists'];
        }


        return $response;
    }

    ...

Комментарий Модель:

class Comment extends Model
{
     // All the code that loads replies recursively is here...
     ...

     public function isRepliesLoaded() {
          return isset($this->relations['replies']);
     }

     public function loadReplies() {
          return $this->load('replies.user');
     }

     public function loadRecursiveReplies()
     {
        if (!$this->isRepliesLoaded()) {
            $this->loadReplies();
        }

        if ($this->replies->isEmpty()) {
            return;
        }

        foreach ($this->replies as $reply) {
            $reply->loadRecursiveReplies();
        }
    }

     ...
}

Рекомендация Модель:

class Recommendation extends Model
{
    ...
    // This will prepend site url in your file path when you access with `$this->file` automatically.
    public function getFileAttribute($value) {
        return 'https://example.com/' . $value;
    }
    ...
}

PS: Этот код не тестировался.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...