1

I am trying to figure out the correct way to implement a polymorphic relationship in Laravel using the example case of allowing the same "Comment" model to have a relationship with both "Posts" and "Videos".

This is the same example as in the Laravel docs, as follows:

posts
    id - integer
    title - string
    body - text

videos
    id - integer
    title - string
    url - string

comments
    id - integer
    body - text
    commentable_id - integer
    commentable_type - string

I have the models set up with the relationships back and forth - no issue there. My question is how to make most efficient use of the CommentsController? I would like to be able to use the same CommentsController@store method to store any type of comment, whether it be for a post or a video.

This, rather than the alternative of having a CommentsController@storePostComment and a CommentsController@storeVideoComment.

I have my routes set up as follows:

Route::post('/posts/{post}/comments', 'CommentsController@store'); 
Route::post('/videos/{video}/comments', 'CommentsController@store');

I have my CommentsController@store method set up as follows, currently for Posts only:

class CommentsController extends Controller
{

    public function store(Post $post)
    {
        $post->addComment(request('body'));      

        return back(); 
    }
}

Laravel's route model binding grabs the correct Post and the addComment() method saves the comment.

My question is how can I modify this to accept either a Post or a Video to the same method? I am sure this is the correct way to do it rather than creating separate methods for each, but not sure how to go about it.

2 Answers 2

3

Try Using SEGMENT

public function store($data)  //{post} or {video} comes here
{
   if(Request::segment(1) == 'posts'){
       $post = new Post;
       $post->addComment(request('body'));
   }else if(Request::segment(1) == 'videos'){
       $video = new Video;
       $video->addComment(request('url'));
   }     
   return back(); 
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the reply. I am going to do it this way for now! I was hoping there was a way to automatically detect the type and assign... something along the lines of an interface, but will keep trying to figure that out.
Have you gotten any further regarding this?
0

You can also instantiate the model on the fly from a string, although you'd probably want to whitelist valid model types:

public function store(str $model)
{
    $model = 'App\\Models\\'.ucfirst(Request::segment(1));
    $model = new $model;
    $model->addComment(request('body'));      

    return back(); 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.