Laravel save / update many to many relationship

后端 未结 4 849
日久生厌
日久生厌 2020-12-07 07:28

Can anyone help me on how to save many to many relationship? I have tasks, user can have many tasks and task can have many users (many to many), What I want to achieve is th

相关标签:
4条回答
  • 2020-12-07 07:35

    tldr; Use sync with 2nd param false


    Many-to-many relationship is belongsToMany on both models:

    // Task model
    public function users()
    {
      return $this->belongsToMany('User', 'user_tasks'); // assuming user_id and task_id as fk
    }
    
    // User model
    public function tasks()
    {
      return $this->belongsToMany('Task', 'user_tasks');
    }
    

    In order to add new relation use attach or sync.

    Difference between the two is:

    1 attach will add new row on the pivot table without checking if it's already there. It's good when you have additional data linked to that relation, for example:

    User and Exam linked with pivot table attempts: id, user_id, exam_id, score

    I suppose this is not what you need in your situation:

    $user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]
    
    $user->tasks()->attach([5,6,7]);
    // then
    $user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,5,6,7]
    

    2 sync on the other hand, will either remove all relations and set them up anew:

    $user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]
    
    $user->tasks()->sync([1,2,3]);
    // then
    $user->tasks()->getRelatedIds(); // [1,2,3]
    

    or it will setup new relations without detaching previous AND without adding duplicates:

    $user->tasks()->sync([5,6,7,8], false); // 2nd param = detach
    // then
    $user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,7,8]
    
    0 讨论(0)
  • 2020-12-07 07:44

    The sync function obliterates the exiting relationships and makes your array the entire list of relations. You want attach instead to add relations without removing others.

    0 讨论(0)
  • 2020-12-07 07:53

    syncWithoutDetaching([$id_one, $id_two, $id_three]); is what you are looking for. Actually it does the exact thing [sync with 2nd param false] does!

    0 讨论(0)
  • 2020-12-07 07:56

    Here's my notes on how to save and update on all the Eloquent relationships.

    in One to One:

    You have to use HasOne on the first model and BelongsTo on the second model

    to add record on the first model (HasOne) use the save function

    example:    $post->comments()->save($comment);

    to add record on the second model (BelongsTo) use the associate function

    example:    $user->account()->associate($account);    $user->save();


    in One to Many:

    You have to use HasMany on the first model and BelongsTo on the second model

    to add record on the first table (HasMany) use the save or saveMany functions

    example:    $post->comments()->saveMany($comments);

    to add record on the second model (BelongsTo) use the associate function

    example:    $user->account()->associate($account);    $user->save();


    in Many to Many:

    You have to use BelongsToMany on the first model and BelongsToMany on the second model

    to add records on the pivot table use attach or sync functions

    • both functions accepts single ID or array of ID’s 

    • the difference is attach checks if the record already exist on the pivot table while sync don’t

    example: $user->roles()->attach($roleId);


    in Polymorphic One to Many:

    You have to use MorphMany on the main model and MorphTo on all the (***able) models

    to add records on all the other models use the save

    example:    $course->tags()->save($tag);

    the pivot table should have the following columns:

    . main model ID

    . (***able) ID

    . (***able) Type


    in Polymorphic Many to Many:

    You have to use MorphByMany on the main model and MorphToMany on all the (***able) models

    to add records on all the other models use the save or saveMany

    example:    $course->tags()->save($tag);

    example:    $course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);

    the pivot table should have the following columns:

    . main model ID

    . (***able) ID

    . (***able) Type


    in Has Many Through (shortcut):

    You have to use HasManyThrough on the first table and have the normal relations on the other 2 tables

    this doesn’t work for ManyToMany relationships (where there’s a pivot table)

    however there’s a nice and easy solution just for that.


    Here's an article I wrote, inspired by this answer. Important to check it: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209

    0 讨论(0)
提交回复
热议问题