ahuggins's avatar

Inserting Polymorphic Relations

So I have a comments table, Comment model that I am setting up to handle polymorphic relations to multiple models.

Everything is working, I just can’t figure out if there is a cleaner way to create records. Right now I have

            'body' => $request->body,
            'commentable_id' => $post->id,
            'commentable_type' => get_class($post)
        ]);```

But I am going to have to specify the array attributes anytime I want to create a comment, like 'commentable_type' and 'commentable_id' are never going to be from form data. But I would prefer to not have to specify this in each controller to create a new comment record.

on most models you can do `Post::create($requeset->all())` and it’s cool

I am just wondering if there is a way that I can make it simpler each time I want to insert a new comment (at the code inserted above)?

I was thinking I could override the ‘create’ method on the Comment model, pass the attributes to my method as well as what model it should be attached to, then in my create method, setup the attributes, and call the parent ‘create’ method. But that didn't seem to work, and I think that's because in the above code 'comments()' isn't returning an instance of Comment class, but the Builder class, which I think is correct.

I've searched the docs and searched multiple resources. Can't quite find this one. 

Any thoughts? Thanks in advance!
0 likes
4 replies
sutherland's avatar
Level 28

Retrieve the model you are attaching the comment to, then use the save or create method.

For example:

$comment = new App\Comment(['body' => $request->body]);

$post = App\Post::find($post->id);

$comment = $post->comments()->save($comment);
9 likes
ahuggins's avatar

Oops, some of my code sample got cut out.

My code sample should have been:

Auth::user()->comments()->create([
            'body' => $request->body,
            'commentable_id' => $post->id,
            'commentable_type' => get_class($post)
        ]);

So I agree yours is the right way to do that. But I also had an issue of having to pass the user_id...which didn't feel great. But someone on Larachat suggested listening for the "Comment::creating" event. Then I could set the Authenticated user_id there and not have to set it everytime.

Thanks for your help!

4 likes
yassineqoraiche's avatar

Actually you don't need to insert commentable_id and commentable_type it will be passed automatically. you can just:

$user->comments()->create([
            'body' => $request->body,
        ]);
5 likes

Please or to participate in this conversation.