41

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?

1
  • What's the error? Commented Mar 22, 2017 at 11:21

7 Answers 7

51

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);
Sign up to request clarification or add additional context in comments.

5 Comments

If it's not work, edit your post and explain your relationship for us
Thank you. That fixed it. I was so close.
@João Mantovani Seems you can help me. Look at this : stackoverflow.com/questions/49512956/…
@JoãoMantovani how it is possible that u have videos() relation on the tag() model if tag() is the polymorphic model with taggable() morphTo()?
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.
25

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

$tag->videos()->associate($video)->save();

1 Comment

Only this one works for me
2

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);

Comments

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

Comments

0

I use this code:

$post->comments->attach($comment);

Comments

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

Comments

0
$post = Post::create([
  'title' => 'test title',
  'description' => 'test description',
  'status' => 1,
  ]);

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

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.