LaraNewDev's avatar

can't access ID on pivot table to use it in a activity/log table.

Hello everybody,

First I will explain the context, then the problem, then what I've got.

I am developing a practice app which emulates a blog. Any registered user can like a post, but also, can like other things, such as comments of a post. To do so, I created a polymorphic relationship. This feature works. This is the schema:

public function up()
{
    Schema::create('likeables', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('user_id');
        $table->unsignedBigInteger('likeable_id');
        $table->string('likeable_type');
        $table->timestamps();

        $table->unique(['user_id', 'likeable_id','likeable_type']);

        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        


    });
}

There is a model named like, which has some methods to like, unlike and those things. It all works well, I am still not describing the problem, just giving context. The model is:

protected $table = 'likeables';

protected $fillable = [
    'user_id',
    'likeable_id',
    'likeable_type',
];

/**
 * Get all of the comments that are assigned this like.
 */
public function comments()
{
    return $this->morphedByMany('App\Comment', 'likeable');
}

/**
 * Get all of the posts that are assigned this like.
 */
public function posts()
{
    return $this->morphedByMany('App\Post', 'likeable');
}

public function path()
{
    //TODO. EL path será diferente segun "likeable"
}

public function activity()
{
    dump($this->id);//THIS RETURNS NULL, I can do $this->"anyOtherColumn" and it works.
    return $this->morphMany(Activity::class, 'subject')->latest();//This should return subject_Type and subject_id, but it only returns the first one
}

public function recordActivity($description)
{
    $this->activity()->create([
        'profile_id' => auth()->user()->profile->id,
        'description' => $description
    ]);
}

}

So, notice the method "activity()", that has a comment. I would like to obtain the ID. Why? I'll explain.

Aside from the liking functionality, I am doing a log or activity table. When the user creates a post, or a coment, or LIKES a post or coment, a entry must appear. I did it with Observers and It works flawlessly with posts or comments, but with likes, it does so so. The entry appears, but I cannot identify the ID of the row of the likeables table. I need this information because from there I can get to know if the thing liked was a comment or a post, and which one specifically.

I show you the schema for activity, but I don't think the problem is related. The problem is in the likeables table. I think laravel, in this kind of relationship, does not want to use the id.

public function up()
{
    Schema::create('activities', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('profile_id');
        $table->nullableMorphs('subject');
        $table->string('description');
        $table->text('changes')->nullable();
        $table->timestamps();

        $table->foreign('profile_id')->references('id')->on('profiles')->onDelete('cascade');
    });
}

To sumarize, when I want the morph field 'subject', I get the subject_type and subject_id if the type is POST or COMMENT, but when it is LIKE, I do not get the subject_id. I think this happens because LIKE model is an intermidiate table.

If I dump and die and inspect the LIKE model, in the array field I see no ID, just the other columns. See example (sorry, I don't know how to format nicely in the forum):

#attributes: array:5 [ "user_id" => 4 "likeable_id" => 1 "created_at" => "2020-04-19 21:03:04" "updated_at" => "2020-04-19 21:03:04" "likeable_type" => "App\Comment" ]

Somehow I need laravel to use the ID column I think. To try so, I read the docs and SO and this forum for some time, and thought that the answer was to add at the likeable models (aka, comment, post) the following:

public function likes()
{
    return $this->morphToMany('App\User', 'likeable')
        ->using('App\Like')
        ->withPivot('id') //This line I have added, but no result
        ->withTimestamps();
}

But it did not work, no behavior change with or without the line.

Thanks a lot

0 likes
1 reply
LaraNewDev's avatar

Hello,

Just in case is interested, I found a workaround. This may be useful for somebody in my situation. I don't like it because it breaks symmetry. When I want to record activity of a likeable, I don't store in the activity table the information related to the like. Rather I go straight to the entity that was liked.

public function recordActivity($description)
{   //
    Activity::create([
        'profile_id' => auth()->user()->profile->id,
        'description' => $description,
        'subject_id' => $this->likeable_id,
        'subject_type' => $this->likeable_type
    ]);
}

It works, but I do not have inner peace doing it this way because I am not using the Eloquent relationship as I do when I log creation of posts or creation of comments. If anybody knows how to fix the original issue, please advisme how to proceed.

1 like

Please or to participate in this conversation.