37

I'm reading the tutorial* on how to define many-to-many polymorphic relationships in Laravel but it doesn't show how to save records with this relationship.

In the their example they have

class Post extends Model
{
    /**
     * Get all of the tags for the post.
     */
    public function tags()
    {
        return $this->morphToMany('App\Tag', 'taggable');
    }
}

and

class Tag extends Model
{
    /**
     * Get all of the posts that are assigned this tag.
     */
    public function posts()
    {
        return $this->morphedByMany('App\Post', 'taggable');
    }

    /**
     * Get all of the videos that are assigned this tag.
     */
    public function videos()
    {
        return $this->morphedByMany('App\Video', 'taggable');
    }
}

I've tried saving in different ways but the attempts that makes most sense to me is:

$tag = Tag::find(1);
$video = Video::find(1);
$tag->videos()->associate($video);

or

$tag->videos()->sync($video);

None of these are working. Can anyone give me a clue on what I could try?

Dubby
  • 2,290
  • 4
  • 27
  • 38

7 Answers7

48

It's simple like that, see this section.

Instead of manually setting the attribute on the videos, you may insert the Comment directly from the relationship's save method:

//Create a new Tag instance (fill the array with your own database fields)
$tag = new Tag(['name' => 'Foo bar.']);

//Find the video to insert into a tag
$video = Video::find(1);

//In the tag relationship, save a new video
$tag->videos()->save($video);
João Mantovani
  • 2,230
  • 1
  • 21
  • 33
  • If it's not work, edit your post and explain your relationship for us – João Mantovani Mar 22 '17 at 11:26
  • 1
    Thank you. That fixed it. I was so close. – Dubby Mar 22 '17 at 11:47
  • @João Mantovani Seems you can help me. Look at this : https://stackoverflow.com/questions/49512956/how-can-i-add-delete-and-get-a-favorite-from-product-with-polymorphic-relations – moses toh Mar 27 '18 at 13:10
  • @JoãoMantovani how it is possible that u have videos() relation on the tag() model if tag() is the polymorphic model with taggable() morphTo()? – llioor Apr 01 '19 at 11:34
  • 1
    Instead of `$tag->videos()->save($videos)` do `$video->tags()->save($tag)` because the video model has many tags and setup `morphTo` in your `video` model. – Oussama Aug 07 '21 at 15:08
22

you missed a step in the associate method, use this:

$tag->videos()->associate($video)->save();
Kurt Chun
  • 391
  • 4
  • 9
1

You can also try this which worked for me (morphMany):

$rel_data = ['assigned_type'=>'User','assigned_id'=>$user_model->getKey()];

$event->assigned_models()->create($rel_data);
Andrew
  • 1,126
  • 11
  • 28
0

And if you want to save multi tags you can use code below

route:

Route::post('posts/{id}/tags', 'PostController@storeTags');

your request sends tags as array contains ids

+ Request (application/json) or (form-data)
        {
            "tags": [
              1,2,3,4
            ]
        }

in your controller:

public function storeTags(Request $request, $id)
{
    foreach ($request->tags as $id)
        $tags[] = Tag::find($id);

    $post= Post::find($id);
    $post->tags()->saveMany($tags);

}

and for update:

// sync() works with existing models' ids. [here means: $request->tags]
$post->tags()->sync([1,2,3]); // detaches all previous relations
$post->tags()->sync([1,2,3], false); // does not detach previous relations,attaches new ones skipping existing ids
Ali Sharifi Neyestani
  • 4,162
  • 1
  • 14
  • 22
0

I use this code:

$post->comments->attach($comment);
showdev
  • 28,454
  • 37
  • 55
  • 73
0

Comment.php

class Comment extends Model
{
use HasFactory;
protected $fillable = ['body','comment_id','comment_type'];
public function commentable()
{
    return $this->morphTo();
}
}

MainController.php

 public function addPost(){
    //add Post
    //Create a new Tag instance (fill the array with your own database fields)
    $post = new Post(['post_name' => 'something post ']);
    
    //Find the comment to insert into a post
    $comment =  Comment::find(1);

    //In the comment relationship, save a new post
    $post->save();
    return ("Post Added");
    }

web.php

Route::get('/add-post',[MainController::class,'addPost']);

https://laravel.com/docs/5.4/eloquent-relationships#inserting-and-updating-related-models

Sarthak Raval
  • 1,001
  • 1
  • 10
  • 23
0
$post = Post::create([
  'title' => 'test title',
  'description' => 'test description',
  'status' => 1,
  ]);

$post->comment()->create([ 'body' => "test body",'user_id' => 1]);
Mohd Anas
  • 11
  • 1
  • 1