Blueberry
Blueberry

Reputation: 2231

Eloquent relations - add (but don't save) to belongsToMany

I would like to create en Eloquent model without saving it to the database right away. I would, however, like to include all relationships so that with a single "push()" call I could save the entire structure.

The below example shows what I am trying to to. I have the following relationships set up:

class Post extends Eloquent
{
    public function tags()
    {
        return $this->belongsToMany('Tag');
    }
}

class Tag extends Eloquent
{
    public function posts()
    {
        return $this->belongsToMany('Post');
    }
}

Pretty standard, a post can have many tags, and a tag can belong to many posts.

I understand I can simply do this now:

//save the post
$post = new Post;
$post->save();

//assign the tag
$post->tags()->save($tag);

However, what I really am looking for is:

//create the post
$post = new Post;

//assign the tag (without saving anything yet!)
$post->tags()->add($tag);

//save the whole thing
$post->push();

The relevant docs are here but it seems there is no mention of "add" on belongsToMany rather than "save".

Any help appreciated.

Upvotes: 3

Views: 3464

Answers (1)

ExohJosh
ExohJosh

Reputation: 1892

This is actually pretty easy, when you understand what

$post->tags()->add($tag);

does. This is going to access the tags relationship ala query builder but what you're looking to do simply add tag/s to your post.

Laravel doesn't have a built in way to handle this but you could easily approach it like so:

See below

$post->addTag($tag); // Adding a tag to our tag array


protected $attributes = [
   'tags' => [],    
];

//type hint a tag and push the tag into our tags attribute
public function addTag(Tag $tag) { 
   array_push($this->attributes['tags'], $tag);
}


//Iterate over the tags and attach them to our Post model, 
also save the post model after.

public function push() {
  return collect($this->attributes['tags'])->each(function($tag){
     $this->attach($tag);
  });
  $this->save();
}

I haven't tested the code but this will hopefully get you set on the right path. I would also be interested in knowing why you have found your self pushing towards this implementation? I haven't found a use case for something like this before and may be able to assist you find a more standardised way of handling your use case.

Upvotes: 3

Related Questions