Search code examples
phplaravelormlaravel-5many-to-many

Correct way to define many to many relationship with Laravel


I have two models:

BlogPost model:

class BlogPost extends Model {

    protected $table = 'blog_posts';

    public function categories()
    {
        return $this->belongsToMany( 'BlogCategory', 'blog_category_post', 'post_id', 'category_id' );
    }

}

and BlogCategory model:

class BlogCategory extends Model {

    protected $table = 'blog_categories';


    public function posts()
    {
        return $this->belongsToMany( 'BlogPost', 'blog_category_post', 'category_id', 'post_id' );
    }

}

Is it the correct way of using the 3rd and 4th parameters in belongsToMany() for the 2 models ?

It seems to be working because the pivot table is filled when attach() method is called:

if ( is_array( $request->get('categories') ) && count( $request->get('categories') ) ) {
            $post->categories()->attach( $request->get('categories') );
        }

but fails when using detach() with this error:

Call to undefined method Illuminate\Database\Eloquent\Collection::detach()

foreach ( $post->categories as $category ) {
            $post->categories->detach( $category->id );
            echo "<br />" . $category->id;
        }

Solution

  • You have call detach on the relation instance, not the collection.

    foreach ($post->categories as $category) {
        $post->categories()->detach($category->id);
        //               ^^
    }
    

    BTW, it seems you want to remove all categories. You can achieve that by simply not passing anything to the detach method:

    $post->categories()->detach();
    

    Much more efficient.