Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ahmadbadpey's avatar

get included reply in a recursive relationship in laravel 5

I have a table named replies contains all replies of a topic in a Forum laravel application.

**replies Table**
---------------
    reply_id
    content
    topic_id
    reply_by
    embed_reply
    created_at
    updated_at

replies can have another reply Herself.fo that there is embed_reply column that hold reply_id of included reply.

Now I want details of included reply would have existed on the parent Reply on fetching.

for that i add this Method to reply Model :

public function included_reply ()
        {
            return $this->with('replies', function ($query) {
                $query->where('reply_id',$this->embed_reply);
            });
        }

And for fetching replies of a specific Topic, I wrote this :

$topic = Topic::whereTopicId($id)
                ->with([
                    'replies' => function ($query) {
                        $query->orderBy('created_at', 'desc');
                    }
                    , 'replies.included_reply'
                ])
                ->first();

all of this return bellow Error:

BadMethodCallException in Builder.php line 2071:
Call to undefined method Illuminate\Database\Query\Builder::replies()

and I do not know how to do that. what is solution?

0 likes
5 replies
bobbybouwmann's avatar

Did you add the relation? And if you did so, how did you create the relation? It seems like the relation doesn't exists on the Topic model

ahmadbadpey's avatar

I write included_reply in Reply method only and call it via replies.included_reply. I did not write Topic Model here Because I thought it does not require.

if a relationship except included_reply is required ,What is it?

ahmadbadpey's avatar

This is Topic Model :

<?php

    namespace App;

    use Cviebrock\EloquentSluggable\SluggableInterface;
    use Cviebrock\EloquentSluggable\SluggableTrait;
    use Illuminate\Database\Eloquent\Model;

    class Topic extends Model implements SluggableInterface
    {
        use SluggableTrait;

        protected $sluggable = [
            'build_from' => 'topic_subject',
            'save_to'    => 'topic_alias',
            'on_update'  => true
        ];

        protected $guarded    = ['created_at', 'updated_at'];
        protected $primaryKey = 'topic_id';
        protected $dateFormat = 'U';

        public function getCreatedAtAttribute ($value)
        {
            return $value;
        }
        
        public function replies (){
         return $this->hasMany('App\Reply');
        }
        public function user (){
            return $this->belongsTo('App\User','topic_by','user_id');
        }

    }

And this is Reply Model :

<?php

    namespace App;

    use Illuminate\Database\Eloquent\Model;

    class Reply extends Model
    {
        protected $guarded    = ['created_at', 'updated_at'];
        protected $primaryKey = 'reply_id';
        protected $dateFormat = 'U';

        public function getCreatedAtAttribute ($value)
        {
            return $value;
        }

        public function included_reply ()
        {
            return $this->with(['replies'=> function ($query) {
                return $query->where('reply_id',$this->embed_reply);
            }])->get();
        }

        public function topics ()
        {
            return $this->belongsTo('App\Topic');
        }

        public function user ()
        {
            return $this->belongsTo('App\User', 'reply_by', 'user_id');
        }

        public function files ()
        {
            return $this->hasMany('App\Userfile');
        }


    }

And this is show method on Topic Controller:

public function show ($alias)
        {
            $topic = Topic::whereTopicAlias($alias)
                ->with([
                    'replies' => function ($query) {
                        $query->orderBy('created_at', 'desc');
                    }
                    , 'replies.included_reply'
                ])
                ->first();
//          return $topic;
            return view('main.pages.forum.topic', ['topic' => $topic]);
        }

Reply Table :

    reply_id
    content
    topic_id
    reply_by
    embed_reply
    created_at
    updated_at

Topic Table :

    topic_id
    topic_subject
    topic_alias
    topic_by
    views_count
    replies_count
    created_at
    updated_at

These are all things that I have

pmall's avatar
pmall
Best Answer
Level 56

There must be a relationship between your parent reply and your child reply :

public function embed()
{
    return $this->belongsTo(Reply::class, 'embed_reply');
}
$reply = Reply::find($reply_id);
$embed = $reply->embed;

Please or to participate in this conversation.