Search code examples
phplaravelmany-to-many

Laravel many-to-many polymorphic relationships sql error while seeding


Hello mine foreach loop returns a Call to a member function bookmarkItems() on int, when I try to seed mine database. I don't understand what I am missing laravel docs poly relation I have setup the relationsships like this and then when I am trying to save the new bookmarkitem is returns the error. stack overflow post about saving I have tried save or attach but both return the same error I don't see what I am missing in the code.

Edit:

After seeing that Post::all()->random()->id should have beem Post::all()->random() it returns this error

SQLSTATE[HY000]: General error: 1364 Field 'bookmarks_id' doesn't have a 
default value (SQL: insert into `bookmark_items` (`bookmark_items_id`, 
`bookmark_items_type`) values (5, App\Models\Post))

What means when attaching or saving the new bookmarkitem it doesnt add the $bookmarkItems->bookmarks_id = Bookmark::all()->random()->id; cause its not inserting that in the database while im setting it before saving the new bookmark item in the database?

Migration

    Schema::create('bookmark_items', function (Blueprint $table) {
        $table->id();
        $table->integer('bookmark_items_id')->unsigned();
        $table->string('bookmark_items_type');
        $table->unsignedBigInteger('bookmarks_id');
        $table->foreign('bookmarks_id')->references('id')->on('bookmarks');
        $table->timestamps();
    });

Classes

class Post extends Model
{
    public function bookmarkItems()
    {
         return $this->morphToMany(BookmarkItems::class, 'bookmark_items');
    }
}

class Comment extends Model
{
     public function bookmarkItems()
    {
        return $this->morphToMany(BookmarkItems::class, 'bookmark_items');
    }
}


class BookmarkItems extends Model
{

    public function posts(): \Illuminate\Database\Eloquent\Relations\MorphToMany
    {
        return $this->morphedByMany(Post::class, 'bookmark_items');
    }


    public function comments(): \Illuminate\Database\Eloquent\Relations\MorphToMany
    {
        return $this->morphedByMany(Comment::class, 'bookmark_items');
    }
}

Foreach function

   foreach ((range(1, 6)) as $index) {
       $post = Post::all()->random()->id;
       $bookmarkItems = new BookmarkItems();
       $bookmarkItems->bookmarks_id = Bookmark::all()->random()->id;
       $post->bookmarkItems()->save($bookmarkItems);
   }

Solution

  • https://laravel.com/docs/7.x/eloquent-relationships#updating-many-to-many-relationships

    $post->bookmarkItem()->attach($bookmarkItem, ['bookmarks_id' => Bookmark::all()->random()->id]);
    

    just had to give the additional data to be inserted like this bookmarks_id so the end result would be like this

    foreach ((range(1, 6)) as $index) {
            $post = Post::all()->random();
            $bookmarkItem = new BookmarkItem();
            $post->bookmarkItem()->attach($bookmarkItem, ['bookmarks_id' => Bookmark::all()->random()->id]);
    }