laraveleloquent-relationship

Saving a Post and a Video into a relational model using Laravel eloquent


I have created a migration name savables as follows, the goal is to attach, and detach the post_id or video_id along with its model type.

Schema::create('savables', function (Blueprint $table) {
   $table->unsignedBigInteger('savable_id');
   $table->string('savable_type');
});

The User, Post and Video Models contains the following functions

/* Post and Video Models */
public function users_saved(): MorphToMany
{
   return $this->morphToMany(User::class, 'savable');
}
/* User Model */
public function saved_posts(): MorphToMany
{
   return $this->morphedByMany(Post::class, 'savable');
}

public function saved_videos(): MorphToMany
{
    return $this->morphedByMany(Video::class, 'savable');
}
>$post->saved_posts()->attach(auth()->id());
=null

Solution

  • Yess! I have solve this using OneToMany(Polymorphic Relationship) Read more about it

    https://laravel.com/docs/11.x/eloquent-relationships#one-to-many-polymorphic-relations

    Use Save instead of Comment and all the logics will be the same.

    Edit

    1. Create Save Model Along with its migrations saves
    $php artisan make:model -m Save
    
    1. Edit migration file
    Schema::create('saves', function (Blueprint $table) {
      $table->id();
      $table->unsignedBigInteger('savable_id');
      $table->string('savable_type');
      $table->foreignId('user_id')->constrained();
      $table->timestamps();
    });
    
    1. In Post and Video Models Put this
    public function saves(): MorphMany {
      return $this->morphMany(Save::class, 'savable')->chaperone();
    }
    
    1. In Save Model Put this
    public function savable(): MorphTo {
      return $this->morphTo();
    }
    
    1. Now you can start saving the Post and Video(In your controller)
    $post->saves()->create([ 'user_id' => auth()->id()]);
    $video->saves()->create([ 'user_id' => auth()->id()]);
    
    1. To access this by User side,
    In User Model, 
    public function saves() {
      return $this->hasMany(Save::class);
    }
    //Now you can tweak this anywhere
    $user->saves->where('savable_type', 'post'); //User will get the saved Posts
    $user->saves->where('savable_type', 'video'); //User will get the saved Videos